Docker 和 Vagarant 有什麼不同?
如果在每個專案同時運行多個容器(container)的情況下 Docker 比 Vagrant 好在哪裡?會比用 Vagrant 同時跑多部虛擬機的方式差嗎?No,原因如下述。
Docker 映像是可擴展的(Extendable)
Docker 映像可擴展它的父映像(parent image),這點讓 Docker 映像更加類似於 PHP 類別(class)。例如一個 Nginx Docker 映像可擴展自
phusion/baseimage Docker 映像,並且 phusion/baseimage 也擴展自最父層(top-most)的
ubuntu Docker 映像。每一個子映像只會包含與父映像有差異的部份,也就是說 ubuntu 映像只是一個小型的Ubuntu 作業系統;而 phusion/baseimage 裡面只有一些用於強化 Docker 容器(container)與作業的工具;最後的 Nginx 映像裡面也只有 Nginx 網頁伺服器和它的組態檔案。
互不相關的 Docker 映像也有可能擴展自同一個父輩(ancestor)映像,Docker 也鼓勵這麼做,如此一來那些被重複運用的映像只要下載一次就好。舉例來說,如果一個 Nginx 和另一個 PHP-FPM 映像都擴展自同樣的 ubuntu:14.04 Docker 映像,那麼這個共同的 Ubuntu 映像只要下載一次就好了。
Docker 容器是輕量的(Lightweight)
Docker 容器是輕量的並且僅需求少量的系統資源就可運作,實際上只要需要的 Docker 映像下載好後,把一個 Docker 映像實例化(instantiating)成 Docker 容器跑起來只需要花幾秒鐘的時間,相較之下用 vagrant up –provision 去建構及腳本化實現(provision)一台虛擬機時常常都要花個 15 - 30 分鐘的時間。這樣的高效率基於兩個原因,首先每個 Docker 容器其實就只是個沙盒的系統程序(sandboxed system process),一個程序只做一件事;其次,所有的 Docker 容器都跑在一個共享的 Docker 母機(host machine),母機可以是你自己的 Linux 作業系統也可以只是個小型的 Linux 虛擬機。
Docker 容器同時也是暫存的(ephemeral)與免洗的(expendable),你可以摧毀(destroy)與取代(replace)某個 Docker 容器而不致影響到整個大型應用(application)。
假使容器只是暫存的,那我們要如何保存要留下的(persistent)應用資料?我也有過相同疑問。我們透過 Dockr 容器卷宗(volume)保存(persist)應用資料在 Docker 母機上。在後文中談到實例化 MySQL 容器時我們會再談談 Docker 容器卷宗。
相同母機、不同世界
不像 Vagrant,每個專案都需要完整的虛擬機(virtual machine)、檔案系統(filesystem)、與網路架構(network stack),Docker 容器跑在單一個共用的 Docker母機,怎麼辦到的呢?不同的 Docker 容器如果佔用到同樣的檔案系統或系統資源時不會互相衝突(collide)嗎?不會,而且這正是 Docker 的拿手絕活(pièce de résistance)。
Docker 被建立在它自有的低階的 Linux 函式庫上,稱為 libcontainer,這個工具透過對各種 Unix 與 Linux 的轉接器(adapter)來沙盒化單一的系統程序並限制它們存取系統資源。Docker 的 libcontainer 函式庫可讓不同的系統程序共存於同一個 Docker 母機上並且存取它們各自沙盒化的檔案系統與系統資源。
也就是說,Docker 並不只是 libcontainer 而已,Docker 是封裝(encapsulate)了許多包括 libcontainer 內的工具包,它具有 Docker 映像建立(creation)、移植性(portability)、版次性(versioning)、與分享(sharing)的能力。
Docker 具備多方之長(the best of both worlds)。Vagrant 只是個專注於硬體虛擬化的工具,反觀 Docker 更專注於程序隔離(isolation)。Vagrant 與 Docker 都致力達到的開發者的期望目標,它們創建互相隔離的應用運行環境,然而 Docker 以更好的效率與移植性做到這一點。
(待續…)