趙星月
摘 要:Docker是PaaS提供商DotCloud[1]開(kāi)源的一種虛擬化容器技術(shù)。對(duì)于正處于互聯(lián)網(wǎng)云計(jì)算時(shí)代的我們,容器級(jí)別的應(yīng)用服務(wù)已經(jīng)逐步的走進(jìn)了生活的每個(gè)角落,2015年春節(jié)晚會(huì)新浪微博的抽獎(jiǎng)活動(dòng),就讓13億的國(guó)人享受了一次容器技術(shù)給我們帶來(lái)的服務(wù)體驗(yàn)。自Docker發(fā)布以來(lái)容器間的通信模式一直都是一個(gè)技術(shù)研究的課題,那是因?yàn)槿藗冡槍?duì)容器使用的出發(fā)角度各不相同,本文主要針對(duì)Host網(wǎng)絡(luò)通信模式進(jìn)行了深入的研究,發(fā)現(xiàn)這種通信模式存在容器間端口沖突的問(wèn)題,于是針對(duì)這個(gè)問(wèn)題提出了通過(guò)Macvlan[2]構(gòu)建虛擬容器網(wǎng)絡(luò)的技術(shù)解決方案,并通過(guò)實(shí)驗(yàn)證明了該方案的可行性。通過(guò)Macvlan構(gòu)建的虛擬容器網(wǎng)絡(luò)可以讓容器像主機(jī)一樣擁有自己的IP地址和網(wǎng)卡端口等,這樣依附于宿主機(jī)的容器就不必與宿主機(jī)共享端口,從而避免了端口沖突的問(wèn)題。
關(guān)鍵詞:Docker;通信模式;Macvlan
0引言
Docker支持的容器間網(wǎng)絡(luò)通信模式有四種,分別是host模式、container模式、none模式和bridge模式[3]。而被大家廣泛應(yīng)用的host模式卻存在一個(gè)基礎(chǔ)性的端口沖突的問(wèn)題,在同一宿主機(jī)上共存的兩個(gè)容器如果采用host模式是不可以同時(shí)映射宿主機(jī)同一個(gè)端口號(hào)的,否則會(huì)導(dǎo)致后創(chuàng)建的容器啟動(dòng)失敗。而通過(guò)Macvlan為容器創(chuàng)建虛擬Mac地址,從而創(chuàng)建專屬的虛擬網(wǎng)卡,這樣我們就可以為容器創(chuàng)建虛擬的網(wǎng)絡(luò)IP,容器不需要再與宿主機(jī)映射端口號(hào)[6]來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)通信。這樣既避免了Host模式下的端口沖突問(wèn)題,又極大的增加了宿主機(jī)網(wǎng)絡(luò)資源的利用率。本文通過(guò)實(shí)驗(yàn)對(duì)這個(gè)解決方案做出了詳細(xì)的論證與分析。
1Host網(wǎng)絡(luò)通信模式的原理
我們?cè)谒拗鳈C(jī)上創(chuàng)建docker容器,根據(jù)docker引擎的命令語(yǔ)法規(guī)則需要通過(guò)參數(shù)p來(lái)配置需要映射的端口號(hào),例如docker run-name helloworld-p 80:80 helloworld:1.0 tail-f look.log,然后docker引擎會(huì)查詢宿主機(jī)80端口是否被占用,如果被占用則創(chuàng)建容器失敗,如果未被占用,則將宿主機(jī)的80端口分配給helloworld這個(gè)容器,并且該容器不會(huì)創(chuàng)建自己專屬的Network Namespace,而是與宿主機(jī)公用同一個(gè)Network Namespace[8],容器也不會(huì)虛擬出屬于自己的虛擬網(wǎng)卡和IP地址,容器就像宿主機(jī)中啟動(dòng)的一個(gè)軟件一樣共享者宿主機(jī)的網(wǎng)絡(luò)資源,而容器的文件系統(tǒng)和進(jìn)程資源還是與宿主機(jī)是相互隔離的。
1.1Host網(wǎng)絡(luò)通信模式的過(guò)程
當(dāng)外界需要與容器進(jìn)行通信的時(shí)候,需要根據(jù)宿主機(jī)的IP及80端口來(lái)實(shí)現(xiàn)數(shù)據(jù)的傳輸,我們可以在helloworld容器中啟動(dòng)一個(gè)Apache服務(wù)[7],內(nèi)嵌一個(gè)php站點(diǎn)程序,外界會(huì)將訪問(wèn)請(qǐng)求先打到宿主機(jī),宿主機(jī)接收到request請(qǐng)求后會(huì)將請(qǐng)求中轉(zhuǎn)給helloworld容器,通過(guò)映射端口容器將request請(qǐng)求分發(fā)給內(nèi)嵌的Apache服務(wù)器中的php服務(wù),當(dāng)服務(wù)返回response響應(yīng)[4]的時(shí)候會(huì)利用宿主機(jī)的網(wǎng)絡(luò)資源在回傳響應(yīng)數(shù)據(jù),整個(gè)通信過(guò)程結(jié)束。
1.2Host網(wǎng)絡(luò)通信模式暴露的問(wèn)題
通過(guò)上述docker容器的Host網(wǎng)絡(luò)通信模式的原理及通信過(guò)程可知,如果一個(gè)宿主機(jī)中已經(jīng)創(chuàng)建了一個(gè)分配80端口的helloworld容器或者其他進(jìn)程已經(jīng)占用了80端口,那么再想在該宿主機(jī)上創(chuàng)建一個(gè)分配80端口的docker容器就會(huì)產(chǎn)生端口沖突而創(chuàng)建失敗,這個(gè)端口沖突問(wèn)題會(huì)給一系列的自動(dòng)化容器創(chuàng)建機(jī)制帶來(lái)很大的阻礙和運(yùn)維難題[5]。
1.3解決方案
在一臺(tái)宿主機(jī)上啟動(dòng)多個(gè)Docker 容器,通過(guò)Macvlan 在每個(gè)Docker 容器的Network Namespace中創(chuàng)建虛擬以太網(wǎng)卡,因?yàn)槊總€(gè)容器都有健全獨(dú)立的網(wǎng)絡(luò)協(xié)議棧,所以可一個(gè)容器內(nèi)創(chuàng)建的虛擬以太網(wǎng)卡分配[9]和宿主機(jī)同一網(wǎng)段的可用IP地址。這樣一來(lái)所有Docker容器及宿主機(jī)它們之間就都成為了同一局域網(wǎng)段下面的可訪問(wèn)的不同網(wǎng)絡(luò)節(jié)點(diǎn)[10]。因此相同宿主機(jī)中的兩個(gè)容器就可以不必共享宿主機(jī)的Network Namespace,也就是無(wú)需再做端口映射,當(dāng)然也就解決了端口沖突的問(wèn)題。而不同宿主機(jī)間的容器也可以像同一局域網(wǎng)內(nèi)不同主機(jī)一樣的互通互信了。
2實(shí)驗(yàn)驗(yàn)證
2.1實(shí)驗(yàn)環(huán)境
如圖1所示配備兩臺(tái)物理主機(jī):
主機(jī)A:IP地址為192.168.0.155、8G內(nèi)存、8核CPU、500G硬盤(pán)、Centos6.5系統(tǒng)、Docker1.6。
主機(jī)B:IP地址為192.168.0.188、8G內(nèi)存、8核CPU、500G硬盤(pán)、Centos6.5系統(tǒng)、Docker1.6。
2.2實(shí)驗(yàn)過(guò)程
在主機(jī)A中安裝docker1.6,然后通過(guò)dockerfile[10]制作測(cè)試鏡像Image test:1.0(測(cè)試鏡像是包含Nginx、php-fom、mysql等服務(wù)的可以收發(fā)https測(cè)試請(qǐng)求的Server),然后根據(jù)Image test:1.0在主機(jī)A中創(chuàng)建并運(yùn)行啟動(dòng)Container 1、Container 2。同理在主機(jī)B中創(chuàng)建Container 3。
Macvlan命令格式:ip link add link eth0 name macv1 type macvlan mode bridge[3]
通過(guò)以上命令行在主機(jī)A中創(chuàng)建Container 1和Container 2的虛擬網(wǎng)卡,并分配IP分別為192.168.0.156和192.168.0.157。
通過(guò)以上命令行在主機(jī)B中創(chuàng)建Container 3的虛擬網(wǎng)卡,并分配IP地址為192.168.0.189。
我們?cè)谌萜髦星度肓藀hp服務(wù)程序,程序中包含一個(gè)隊(duì)列模塊,隊(duì)列是需要發(fā)送https請(qǐng)求的容器服務(wù)IP地址集合(我們預(yù)先設(shè)定好的),服務(wù)程序會(huì)根據(jù)隊(duì)列信息逐一實(shí)現(xiàn)測(cè)試請(qǐng)求[4],并將測(cè)試結(jié)果放入mysql數(shù)據(jù)庫(kù)macvlan database的request_status數(shù)據(jù)表中,實(shí)現(xiàn)測(cè)試結(jié)果的統(tǒng)計(jì)。
2.3實(shí)驗(yàn)結(jié)果
2.4實(shí)驗(yàn)分析
通過(guò)實(shí)驗(yàn)結(jié)果表1證明通過(guò)Macvlan給Container 1、2、3分配的虛擬IP地址是可以完成獨(dú)立的通信服務(wù)的,并且Container 1與Container 2之間不存在端口沖突問(wèn)題了,也就是說(shuō)Container 1、2、3可以隨意通過(guò)彼此的IP地址進(jìn)行網(wǎng)絡(luò)通信而不必再依賴宿主機(jī)的網(wǎng)絡(luò)空間。由此證明通過(guò)將Macvlan創(chuàng)建的虛擬網(wǎng)絡(luò)資源嫁接到容器服務(wù)上是可以實(shí)現(xiàn)容器化的虛擬網(wǎng)絡(luò)的。
3結(jié)語(yǔ)
網(wǎng)卡就是linux的門(mén)戶,協(xié)議棧下面便是網(wǎng)卡,通過(guò)軟件來(lái)實(shí)現(xiàn)對(duì)接,網(wǎng)卡下面連接的就是硬件介質(zhì),而網(wǎng)絡(luò)虛擬化支持任何形式的虛擬化技術(shù),比如虛擬機(jī)或者通過(guò)linux的Network Namespace技術(shù)獨(dú)立的虛擬化空間[8],而通過(guò)Macvlan機(jī)制我們可以將部署的容器網(wǎng)絡(luò)虛擬化出相應(yīng)的節(jié)點(diǎn)[9],讓每個(gè)容器都擁有獨(dú)立的虛擬IP地址,這樣容器之間的通信就不必再依賴于宿主機(jī)的網(wǎng)絡(luò)空間資源,自然就不會(huì)再因?yàn)楣盟拗鳈C(jī)端口而產(chǎn)生容器間的映射端口沖突問(wèn)題了。這不僅方便了容器之間的通信[7],也為基于容器服務(wù)的分布式云計(jì)算技術(shù)解決了最為困難的節(jié)點(diǎn)通信及地址分配的問(wèn)題,極大的提升了任務(wù)調(diào)度的便捷性[5]和靈活性。
參考文獻(xiàn)
[1] 戴王劍,楊保華,曹亞侖.Docker技術(shù)入門(mén)與實(shí)戰(zhàn)[M].西安:機(jī)械工業(yè)出版社,2015:89.
[2] 華為Docker實(shí)踐小組.Docker進(jìn)階與實(shí)戰(zhàn)[M].深圳:機(jī)械工業(yè)出版社,2016:133.
[3] 龔正,吳治輝,葉伙榮,張龍春.Kubernetes權(quán)威指南[M].佛山:電子工業(yè)出版社,2016:327.
[4] 孫宏亮. Docker源碼分析[M].西安:機(jī)械工業(yè)出版社,2015:215.
[5] Joe Johnston,Antoni Batchelli,Justin Cormack,John Fiedler.Docker生產(chǎn)環(huán)境實(shí)踐指南[M].吳佳興,梁曉勇.佛山:人民郵電出版社,2016:76.
[6] Sam Newman.微服務(wù)設(shè)計(jì)[M].崔力強(qiáng),張駿.佛山:人民郵電出版社,2016:301.
[7] 林帆.CoreOS實(shí)踐之路[M].佛山:電子工業(yè)出版社,2015:157.
[8] 張建,謝天鈞.基于docker的平臺(tái)即服務(wù)架構(gòu)研究[D].北京:北京工業(yè)大學(xué)軟件學(xué)院,2014:3.
[9] 楊浚.運(yùn)用Docker技術(shù)搭建linux桌面實(shí)驗(yàn)環(huán)境[D].常州:常州市廣播電視大學(xué),2015:61.
[10] 谷雨.數(shù)據(jù)存儲(chǔ)CockroachDB應(yīng)用技術(shù)Docker的研究[D].哈爾濱:黑龍江省社會(huì)信用辦公室,2015:31.