本文將說明如何透過Docker Volume持久儲存容器資料,並以Docker Network解釋容器網路運作。透過實驗示範,採用內建的DNS伺服器便能解析容器IP位址,整個容器架構只需命名好容器,就可移植到其他Docker伺服器,並結合Docker Volume將WordPress資料庫持久儲存。
首先安裝vShpere Volume Plugin,由於這是Docker文章,便選擇利用容器安裝方式,執行「docker plugin install --grant-all-permissions --alias vsphere vmware/docker-volume-vsphere:latest」,其中「--grant-allpermissions」是取得全部權限,「--alias」則是設定別名。安裝完成之後,執行「systemctl restart docker」指令重新啟動Docker。
此時可用「docker plugin ls」查看目前安裝的外掛程式,確認之後,執行「docker volume create --driver=vsphere --name=ESXVolume -o size=5gb」,其中「--driver」是指定外掛驅動,建立一個名為ESXVolume的Volume。然後輸入「docker volume ls」,可看到DRIVER:vsphere:latest VOLUME NAME:ESXVolume@YOUR_VSPHERE_DISK,亦可使用vSphere Client管理工具,登入後查看YOUR_VSPHERE_DISK儲存設備,當中便會有dockvols目錄,裡面存放著ESXVolume的虛擬硬碟,容量為5GB,如圖2所示。
|
▲圖2 vSphere管理工具儲存畫面。 |
跟前面範例一樣,執行「docker run -ti --name u1 --rm -v ESXVolume:/data ubuntu」,其餘步驟雷同,再次掛載皆可在「/data」目錄中看到持久儲存的檔案和資料,差別只在於資料已經不是存放在本地端的「/var/lib/docker」目錄下,而是透過外掛程式,存放在外部vShpere ESX伺服器中的儲存設備。
這些步驟之外,ESX伺服器端其實還須配合安裝vSphere Installation Bundle(VIB),詳細方式請見vmware/docker-volume-vsphere GitHub專案的README說明。
不只是VMware產品,雲端平台的儲存服務也有提供Plugin外掛,如AWS EFS(https://github.com/ContainX/docker-volume-netshare)、Azure File Service(https://github.com/Azure/azurefiledockervolumedriver)等,讓雲端平台上執行的Docker伺服器,把容器資料放置於外部儲存服務,資料可以更妥善持久保存。
此外,最常見的Volume應用就是存放資料庫資料,如MySQL,將資料庫容器中的「/var/lib/mysql」目錄掛載到本地端,例如執行「docker run --name db -v $(pwd)/db_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=PASSWORD -d mysql:5.7」,避免容器刪除後,重要的資料庫資料也一併銷毀。
Docker Network指令介紹
所有的雲端服務都是以運算、儲存和網路等三種基本要素所構成,而Docker容器技術正好以Docker Engine、Docker Volume和Docker Network相對應。
前一期介紹過Docker Engine,上面解說了Docker Volume的應用方式,接下來便是Docker Network,目的在解決多容器相互溝通的問題,也是整個容器運作中最為複雜的部分,每項服務皆透過連接埠對應,例如HTTP使用80 Port,SSH使用22 Port,其TCP/IP網路堆疊對應至OSI七層架構,可見圖3。未涉及到的TCP/IP基礎知識,建議可自行尋找相關書籍。
|
▲圖3 TCP/IP與OSI模型對應圖。 |
而容器內部網路運作是使用「172.16.0.0」私有網段,其餘私有網段請見表2,在安裝Docker Engine之後,輸入「ifconfig | more」,可見到「docker0」的虛擬網卡,負責容器彼此之間以及外部網路的路由。
表2 三種私有網路區段比較
輸入「docker network ls」,便列出目前預設的Network模式,分別是Bridge、Host和None,容器啟動預設皆為Bridge模式,而Host則是直接使用主機的網路堆疊,例如執行「docker run -ti --name n1 --rm --network=host busybox」,在容器中輸入「ifconfig」,就可列出跟前面一模一樣的網路清單,如圖4所示,至於None模式是完全不使用網路。
|
▲圖4 執行docker network ls查詢結果。 |
在Docker 1.9版之前,未提供Docker Network功能,都是透過Link機制(https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/)來串接多個容器,直到Docker Network出現後。筆者便只使用此功能,不再透過Link方式,因為容器相連更為方便也更清楚,官方亦說明Link將會棄用,而docker network指令清單,請見表3,詳細請參閱官方文件(https://docs.docker.com/engine/reference/commandline/network/),接下來便示範容器網路相關實驗。
表3 docker network指令使用說明
依照原先方式執行容器,所以輸入「docker run -it --rm --name n0 busybox」。在容器內輸入「cat /etc/hosts」,查看主機名稱與IP對應,再執行「ifconfig」,此容器eth0網卡IP位址皆為172.17.0.2,可見容器與docker0網卡是同一網段,輸入「exit」離開容器。
先執行「docker run -itd --name n1 busybox」啟動n1容器,再使用「docker network inspect bridge」指令,列出Bridge模式的詳細內容,當中Subnet為172.17.0.0/16,Gateway是172.17.0.1(docker0網卡),在Containers則列出剛建立的n1容器,而IPv4 Address為172.17.0.2/16。
再來執行「docker run -ti --name n2 busybox」,接著輸入「ping -w3 172.17.0.2」,於容器中ping步驟1的容器IP,會正常回應,但換成ping容器名稱n1,則出現bad address 'n1',表示名稱解析失敗。最後,記得輸入「exit」離開容器。