Docker 1.9新特性:跨主機網(wǎng)絡(luò)為最大亮點
【編者的話】11月4日,Docker 1.9 正式發(fā)布。其中Docker Swarm 和多跨主機網(wǎng)絡(luò)正式可在生產(chǎn)環(huán)境使用,Docker Engine 提供了全新的存儲卷管理系統(tǒng),Docker Compose 對更多環(huán)境提供了更好的支持。所有的這些都為大規(guī)模部署生產(chǎn)環(huán)境下的分布式應(yīng)用打下了堅實的基礎(chǔ)。本文詳細分析了Docker 1.9的種種新特性。
新特性簡介
十一月四號,Docker對1.9進行了發(fā)布,新的發(fā)行版中添加了很多有趣的特性,下面我就對新的發(fā)行版中的新特性做一個簡單的介紹。
- 跨主機網(wǎng)絡(luò):新的網(wǎng)絡(luò)設(shè)備可以支持用戶創(chuàng)建基于多個主機的虛擬網(wǎng)絡(luò),使容器間可以跨網(wǎng)絡(luò)通信。
- 持久化存儲:Docker 1.9 包含一個重新設(shè)計的完整存儲卷管理系統(tǒng),這使得用戶可以更加容易的從前端來管理這些數(shù)據(jù)卷。
- Docker Swarm 1.0:修復(fù)bug并對其進行大量優(yōu)化。Docker公司在1000個節(jié)點上測試了30000個容器,swarm可以如絲般潤滑的運行。
- Docker Engine 1.9:新的Docker Engine中加入了如下新特性:Dockerfile 的構(gòu)建時參數(shù)、并行鏡像 pull、自定義 stop 信號、AWS CloudWatch logging driver和磁盤 I/O metrics。
- Docker Compose 1.5:Docker Compose 是一個定義并運行多容器應(yīng)用的工具,它有如下更新:支持 Windows、Compose 文件中的環(huán)境變量、對多環(huán)境更好的支持、和 networking 集成和Compose file 校驗。
- Docker Toolbox:這個工具可以使Mac和Windows支持這些新特性。
- Docker Registry 2.2:主要做了以下更新:支持 Google Cloud Storage、只讀模式、支持可配置主機名、基于文件的存在配置、可配置的 HTTP 健康檢查和可配置的 HTTP 響應(yīng) headers。詳細的更新說明可以參照《Docker 1.9 發(fā)布:Swarm 和跨主機網(wǎng)絡(luò)進入 production-ready 階段》和Announcing Docker 1.9: Production-ready Swarm and Multi-host Networking。
新特性原理解讀
下面就對我比較感興趣的幾點,做一下詳細的介紹。
首先,此次發(fā)行版最引人注目的就是Docker的跨主機網(wǎng)絡(luò)了。早在六月的DockerCon大會上Docker公司就宣布已經(jīng)開始進行對 Docker Network的試驗性工作。在1.9中docker network命令脫離了實驗分支,正式進入了發(fā)行版中。有了新的Networking我們可以創(chuàng)建虛擬網(wǎng)絡(luò),然后將container加入到虛擬網(wǎng)絡(luò)中,以獲得最適合所部署應(yīng)用的網(wǎng)絡(luò)拓撲結(jié)構(gòu)。
和傳統(tǒng)的links模式相比,新的Networking有如下三點改進:
- 可以跨越不同的物理和虛擬主機,連接不同的容器。
- 用戶可以輕松的停止,開啟和重啟容器,而不用擔心破壞容器之間的相互連接。
- 用戶可以以任何順序創(chuàng)建容器。
在清楚了新的Networking的特性之后,我們來看一下這部分的實現(xiàn)原理。
Networking的跨主機部分使用的時ovs(Open vSwitch)和VXLAN隧道進行實現(xiàn)。關(guān)于容器之間的隔離,則使用了iptables。
要清楚Networking的執(zhí)行流,首先要清楚如下三個概念:
Sandbox:一個Sandbox包含了一個容器的網(wǎng)絡(luò)棧。其中包括容器的管理接口,路由表和DNS設(shè)置。主要是通過namespace和cgroup進行實現(xiàn)。一個Sandbox可以包括多個Endpoint。
Endpoint:一個Endpoint通過加入一個Sandbox來加入一個Network。Endpoint就相當于一個網(wǎng)卡。
Network:一個Network是一組直接互聯(lián)的Endpoint組成的。它相當于一個二級網(wǎng)絡(luò)。
清楚了以上三個基本概念之后我們來看看Network的執(zhí)行流。
指定network的驅(qū)動和各項相關(guān)參數(shù)之后調(diào)用 libnetwork.New()創(chuàng)建一個NetWorkController實例。這個實例提供了各種接口,Docker可以通過它創(chuàng)建新的NetWork和Sandbox等。
通過controller.NewNetwork(networkType, "network1")來創(chuàng)建指定類型和名稱的Network。
通過network.CreateEndpoint("Endpoint1")來創(chuàng)建一個Endpoint。在這個函數(shù)中Docker為這個 Endpoint分配了ip和接口,而對應(yīng)的network實例中的各項配置信息則會被使用到Endpoint中,其中包括iptables的配置規(guī)則和端口信息等。
通過調(diào)用controller.NewSandbox()來創(chuàng)建Sandbox。這個函數(shù)主要調(diào)用了namespace和cgroup等來創(chuàng)建一個相對獨立的沙盒空間。
調(diào)用ep.Join(sbx)將Endpoint加入指定的Sandbox中,則這個Sandbox也會加入創(chuàng)建Endpoint對應(yīng)的Network中。
總的來說,Endpoint是由Network創(chuàng)建的,隸屬于這個創(chuàng)建它的Network,當Endpoint加入Sandbox的時候,就相當于這個Sandbox加入到了這個Network中來。下面的圖可以簡要說明三者的關(guān)系。
然后是關(guān)于Volumes,即持久化存儲這一塊,Docker也做了比較大的改動。首先最明顯的就是--volume不再僅僅作為docker run的一個flag,也作為一個單獨的子命令出現(xiàn)在Docker中。底層也為volume添加了諸如ls、create、inspect和rm等 volume子命令的api。新的volume子命令可以允許用戶先創(chuàng)建volume,然后在啟動的container的時候進行掛載,此舉也更加方便了 volume的管理。
一個簡單的例子方便大家快速上手新特性:
- $ docker volume create --name hello
- hello
- $ docker run -d -v hello:/world busybox ls /world
通過這個例子可以創(chuàng)建一個名為hello的volume,然后將其掛載到容器內(nèi)的/world目錄下。
在Docker Engine 1.9中也有一些有趣實用的特性。
前面提到的磁盤 I/O metrics就是一個很實用的特性。這個新特性通過抓取系統(tǒng)內(nèi)blkio IoServiceBytesRecursive中的信息對磁盤的I/O進行計算,并通過docker state命令打印出來。所以現(xiàn)在通過docker state獲得的容器信息就變成了如下的形式:
并行鏡像 pull也是一個有趣的新特性?,F(xiàn)在可以做到如果用戶pull的鏡像正在被其他進程 pull,進度條會顯示這個信息并正確退出。上一個版本的Docker Engine在處理用戶pull的鏡像正在被其他進程 pull這個問題中,用的是管道,這樣的話就很容易出現(xiàn)管道堵塞,就會卡死在“Layer already being pulled by another client”。
新的版本中使用了名為progressreader的工具包,如果遇到上述問題的話,Docker Engine可以調(diào)用這個工具包,通過共享的Broadcaster讀取其他進程pull用戶所指定鏡像的進度,顯示這個進度,并做出正確的返回。
最后來講講Docker Engine 1.9中的自定義 stop 信號。這個特性可以在Dockerfile 指令中新增 STOPSIGNAL,通過使用這個指令Docker允許用戶自定義應(yīng)用在收到docker stop所收到的信號。這個新特性主要通過重寫Docker中signal庫內(nèi)的stopsignal來支持自定義信號的傳遞,在上層調(diào)用時則將用戶自定義的信號傳入底層函數(shù)即可。
Q&A
Q:請問ovs和vxlan在吞吐和延遲方面有性能損失嗎,有無測試指標?
A:損失肯定是有的,但是具體的指標,Docker方面沒有給出測試結(jié)果。
Q:本地化創(chuàng)建images咋樣了,ovs是本地化嗎,物理網(wǎng)卡需要多少帶寬?
A:這個本次更新沒有提到。ovs的配置會本地化,具體物理網(wǎng)卡多大Docker官方?jīng)]有給出說明。
Q:1.9之后容器的網(wǎng)絡(luò)棧是在容器啟動之前就配置好了還是啟動之后,之前版本的Docker,網(wǎng)絡(luò)初始化是在容器啟動前還是啟動后?
A:網(wǎng)絡(luò)棧啟動之前就會配置,啟動時候進行加載。之前的Docker也是這樣。
Q:docker daemon為跨主機網(wǎng)絡(luò)增加了哪些配置項,跨主機網(wǎng)絡(luò)的信息存放在哪里?
A:這個問題太具體了,需要仔細看看代碼才知道,我只是大概看了一下,畢竟網(wǎng)絡(luò)這部分更新太多了。
Q:請問從1.9開始Docker就支持ovs了么,ovs還是需要自行安裝吧?
A:1.9開始使用ovs實現(xiàn)networking部分,底層還是調(diào)用的ovs。ovs需要自己安裝。
Q:也就是說從1.9以后ovs就是直接通過隧道使用,而不是通過route來實現(xiàn),對么?
A:可以這樣理解。
Q:請問volume特性現(xiàn)在有類似kubernetes persist volume的功能嗎,對接第三方存儲?
A:現(xiàn)在的volume還是對接本地文件夾的,擁有了子命令,更多的是方便使用和管理。
Q:1.9版本特性,是不是更容易建立固定IP類虛擬機的容器?
是的。
Q:跨主機的容器網(wǎng)絡(luò)是由Docker daemon來維護的嗎?
A:是通過daemon維護的。
Q:Docker1.9的CRIU方案相對前幾個版本有哪些改進,新版本使用熱遷移有哪些坑?
A:Docker還是不能熱遷移,runC才可以。
Q:跨主機網(wǎng)絡(luò)功能是全部在docker engine實現(xiàn)的么,還是需要依賴安裝好的ovs相關(guān)環(huán)境?
A:底層還是調(diào)用ovs。
Q:如果容器重啟或重新生成對已經(jīng)構(gòu)建的虛擬網(wǎng)絡(luò)有影響嗎?
A:沒有影響。
Q:D能不能給個1.9網(wǎng)絡(luò)新特性的實際使用的例子?
A:我上面給的那個執(zhí)行流大概就和實際使用的例子類似,就是創(chuàng)建Network,然后創(chuàng)建ep,創(chuàng)建沙盒,將ep裝入沙盒中。實際使用的例子可以參考Docker官方文檔。
Q:多個容器共享一個存儲如何解決同時寫的問題?
A:其實本質(zhì)上Docker的數(shù)據(jù)卷就是一個bindmount,其工作原理和Linux主機上的共享卷原理一致。
===========================
以上內(nèi)容根據(jù)2015年11月5日晚微信群分享內(nèi)容整理。分享人高相林,浙江大學(xué)SEL實驗室碩士研究生,目前在云平臺團隊從事科研和開發(fā)工作。浙大團隊對PaaS、Docker、大數(shù)據(jù)和主流開源云計算技術(shù)有深入的研究和二次開發(fā)經(jīng)驗,團隊現(xiàn)聯(lián)合社區(qū)將部分技術(shù)文章貢獻出來,希望能對讀者有所幫助。 DockOne每周都會組織定向的技術(shù)分享,歡迎感興趣的同學(xué)加微信:liyingjiesx,進群參與,您有想聽的話題可以給我們留言。