Docker映象檔採用aufs檔案架構,是一種分層堆疊的運作方式,先從基礎映象檔開始一層層建立不同Stack的映象檔。

圖片來源: 

Docker

上手Docker的第一步,得先了解Docker建立Container標準化的關鍵,Docker臺北社群召集人郭韋廷建議,也就是要先了解Docker映象檔的運作原理,再開始動手試試看。

Docker是一個Client-Server架構的應用程式,在一個Docker執行環境中,包括了Docker用戶端程式、和在背景執行(Daemon)的Docker伺服器(也稱為Docker Engine),另外還有將Container封裝後的Docker映象檔,用來儲存映象檔的Registry服務。官方提供的映象檔Registry服務就稱為Docker Hub,這是類似Github程式碼Repository儲存服務的映象檔Repository儲存服務。

安裝Docker之後,會提供了一個命令列的用戶端程式來和在背景執行的Docker伺服器溝通。開發者可以直接從Docker Hub下載Docker映象檔(Docker pull指令),再執行(Docker run指令)就可以用這個映象檔來建立一個Container。

郭韋廷解釋,Docker映象檔是一種分層堆疊的運作方式,採用了aufs的檔案架構。要建立一個可提供應用程式完整執行環境的Container映象檔,要先從一個基礎映象檔(Base Image)開始疊起,一層層將不同Stack的Docker映象檔疊加上去,最後組合成一個應用程式所需Container執行環境的映象檔,而每一個Stack也都是可以會匯出成(Docker commit指令)一個映象檔。

舉例來說,假設一個網頁執行環境需要有OS、Apache網站伺服器、MySQL資料庫、Ruby執行環境等不同的Stack。

像郭韋廷最常用的基礎映象檔就是ubuntu映象檔,這是用來建立Container的根目錄架構,若採用了不同的OS映象檔,就會變成是那個OS的目錄架構。

第一個動作就是先下載一個ubuntu的基礎映象檔。只要在命令列輸入sudo docker pull ubuntu,Docker安裝完成後預設pull指令都是存取Docker Hub服務。這個指令會從Docker Hub上下載名稱為ubuntu的映象檔到本機端。

接著,要將新的一層Stack加入ubuntu基礎映象檔中,例如Apache,得先用Docker執行(Docker run指令)這個基礎映象檔,來建立這個映象檔的Container,然後在Container中安裝Apache,安裝完成後,再將Container打包成另一個新的映象檔。

第二層繼續反覆這樣的程序,這時候就是直接從ubuntu-Apache所建立的映象檔開始安裝下一層的MySQL程式,同樣也是先執行ubuntu映象檔,再執行MySQL安裝程序。

說來複雜,實際執行過程,執行映象檔和安裝Apache是一行指令,命令Docker從ubuntu映象檔來建立新的Container同時在這個Container內執行Apache安裝指令。

郭韋廷表示,其實當Apache安裝完成後,Container的壽命也跟著結束了,除非是Daemon式的背景程式,那麼這個Container才會一直存活。就算只是在Container裡面執行一個ls(列出目錄架構)的指令,如sudo docker run ubuntu ls -1。Container也是在ls–l指令結束後也同時關閉了。一行指令就建立了一次Container,也關閉了這個Container。

這段指令是用sudo docker來執行(run)ubuntu這個映象檔,以建立一個ubuntu的Container環境,然後在這個Container中下達ls–l列出系統目錄的指令。當ls- l回傳了Container內ubuntu的檔案目錄,並呈現在螢幕畫面後,ls–l指令結束,這個ubuntu系統的Container壽命也就結束了。

當一個Container結束後,Docker會將這個Container打包成一個暫時性的映象檔,並用一個唯一的Hash值來命名,這個映象檔則儲存在本機端的Docker暫存目錄中。例如剛剛啟用ubuntu映象檔建立Container來安裝了MySQL,裝妥後,這個Container也結束了,而裝妥MySQL後的Container內容則自動打包成一個暫時性的映象檔。我們就可以將這個映象檔匯出成一個長期使用的映象檔,並給予一個名字。

一個Stack就是一層Container映象檔

Docker提供了一個Commit指令,使用Commit指令就可以將Hash值所對應的映象檔,匯出成新的映象檔。郭韋廷表示,Docker之所以用Commit指令,是類似在Github服務用Commit來更新程式碼的意思,是採取差異更新的方式,以原來的ubuntu映象檔為基礎,來建立這個ubuntu-MySQL映象檔。反覆執行Docker來建立新的Stack映象檔時,就如同在原有ubuntu映象檔上疊上一層層新的Stack,最後的映象檔就會變成如ubuntu- Apache-MySQL-Ruby的映象檔。不過這個映象檔的名稱可以自訂,不用像這裡為了說明而以這樣複雜的方式來稱呼。

因為建立Container後是在記憶體中運作,寫在Container內的資料,在Container結束後就消失了,所以,Docker也提供了一個Data Volume參數(docker -v參數),可用來將外部目錄對應到Container內部目錄。

當Container內的程式將資料寫到這個內部目錄時,就等同於將資料寫到所對應的外部目錄。

例如可以設定要執行一個MySQL映象檔時,同時將一個本機端(或雲端)的目錄路徑,設定成Container內部的/mysql目錄,作為MySQL資料庫檔案的所在位置。這樣應用程式每次新增資料到MySQL資料庫時,寫入了Container內的/mysql目錄,也等同於寫入了外部所指定的本地端目錄。當MySQLContainer結束後,外部資料的不會隨著Container終止而消失,下次再度啟動MySQL Container,只要內部/mysql也對應到同樣的本地端目錄,就能取得先前所儲存的資料。

一行指令就能完成執行環境所有部署

因為安裝每一個Stack的程式時,通常也需要這個Stack程式所需的環境配置如指定對應目錄、設定對外溝通的通訊埠等,所以,Docker提供了Dockerfile這個設定檔案,可以將這些建立映象檔的指令全部寫在Dockerfile中,Docker能自動依據這個Dockerfile來建立映象檔(Docker build指令)。這個Dockerfile就等於保存了建立應用程式執行環境所需的所有指令和參數設定,這正是Docker解決開發和維運溝通的最大利器。雙方只要檢視Dockerfile就能清楚知道應用程式目前的執行環境配置。

因為Docker Hub服務不只儲存映象檔,也能連結到Github服務上的Dockerfile,來自動建立映象檔。Dockerfile檔案直接儲存在Github上,就具備了版本控管能力。

開發者不只可以在Docker Hub上搜尋到符合需要的映象檔,例如像ubuntu-Apache-MySQL這樣的組合,Docker Hub也會提供這個映象檔對映到在Github上的Dockerfile。開發者直接Docker命令列指令,一個命令就能從Docker Hub上下載Dockerfile,或載入Github上的Dockerfile,Docker會自動依據Dockerfile內的指令,一一將建立起完整的Docker映象檔,連自己手動下載基礎映象檔都不用。運用Dockerfile記錄所有配置後,只要一行Docker指令就能完成應用程式執行環境的所有部署,你也快來試試看吧。

 

Docker Hub結合GitHub後,只要下載Dockerfile設定檔,就能依據Dockerfile內的腳本指令,自動一步步建立應用程式所需的執行環境映象檔。圖片提供/Docker

 

郭韋廷Docker操作範例

影片網址:http://goo.gl/rO2NlX

 

熱門新聞

Advertisement