????當(dāng)我們開始大規(guī)模使用Docker時(shí)惩阶,會(huì)發(fā)現(xiàn)需要了解很多關(guān)于網(wǎng)絡(luò)的知識(shí)沽翔。Docker容器需要運(yùn)行在一臺(tái)宿主機(jī)上苍息,可以是一臺(tái)物理機(jī),也可以是云上的一臺(tái)虛擬機(jī)千贯。無論是在單主機(jī)上進(jìn)行部署,還是在集群上部署搞坝,總得和網(wǎng)絡(luò)打交道搔谴。
????對(duì)于大多數(shù)單主機(jī)部署來說,問題歸結(jié)于是使用共享卷進(jìn)行數(shù)據(jù)交換桩撮,還是使用網(wǎng)絡(luò)(基于HTTP或者其他的)進(jìn)行數(shù)據(jù)交換敦第。盡管Docker數(shù)據(jù)卷很容易使用峰弹,但也引入了緊耦合,這意味著很難將單主機(jī)部署轉(zhuǎn)化為多主機(jī)部署芜果。自然地鞠呈,共享卷的優(yōu)勢(shì)是速度。
????在多主機(jī)部署中右钾,你需要考慮兩個(gè)方面:?jiǎn)沃鳈C(jī)上的容器之間如何通信和多主機(jī)之間的通信路徑是怎樣的蚁吝。性能考量和安全方面都有可能影響你的設(shè)計(jì)決定。多主機(jī)部署通常是很有必要的舀射,原因是單主機(jī)的能力有限窘茁,也可能是因?yàn)樾枰渴鸱植际较到y(tǒng),例如HGDW脆烟。
1. Docker 網(wǎng)絡(luò)概況
????用一張圖來說明 Docker 網(wǎng)絡(luò)的基本概況:
2. 四種單節(jié)點(diǎn)網(wǎng)絡(luò)模式
2.1 bridge 模式
????Docker 容器默認(rèn)使用 bridge 模式的網(wǎng)絡(luò)山林。其特點(diǎn)如下:
????a.要訪問宿主機(jī)的 IP 以及宿主機(jī)的端口port;
????b.NAT 模式由于是在三層網(wǎng)絡(luò)上的實(shí)現(xiàn)手段,故肯定會(huì)影響網(wǎng)絡(luò)的傳輸效率邢羔。使用一個(gè) linux bridge捌朴,默認(rèn)為docker0;
????c.使用 veth 對(duì),一頭在容器的網(wǎng)絡(luò) namespace 中张抄,一頭在 docker0 上;
????d.該模式下Docker容器不具有公有IP砂蔽,因?yàn)樗拗鳈C(jī)的IP地址與veth對(duì)的 IP地址不在同一個(gè)網(wǎng)段內(nèi);
????e.Docker采用NAT方式,將容器內(nèi)部的服務(wù)監(jiān)聽的端口與宿主機(jī)的某一個(gè)端口port ;進(jìn)行“綁定”署惯,使得宿主機(jī)以外的世界可以主動(dòng)將網(wǎng)絡(luò)報(bào)文發(fā)送至容器內(nèi)部;
????f. 外界訪問容器內(nèi)的服務(wù)時(shí)左驾,需容器擁有獨(dú)立、隔離的網(wǎng)絡(luò)棧极谊;讓容器和宿主機(jī)以外的世界通過NAT建立通信;
iptables 的 SNTA 規(guī)則诡右,使得從容器離開去外界的網(wǎng)絡(luò)包的源 IP 地址被轉(zhuǎn)換為 Docker 主機(jī)的IP地址:
效果是這樣的:
示意圖:
2.2 Host 模式
????Host 模式并沒有為容器創(chuàng)建一個(gè)隔離的網(wǎng)絡(luò)環(huán)境。而之所以稱之為host模式轻猖,是因?yàn)樵撃J较碌?Docker 容器會(huì)和 host 宿主機(jī)共享同一個(gè)網(wǎng)絡(luò) namespace帆吻,故 Docker Container可以和宿主機(jī)一樣,使用宿主機(jī)的eth0咙边,實(shí)現(xiàn)和外界的通信猜煮。換言之,Docker Container的 IP 地址即為宿主機(jī) eth0 的 IP 地址败许。其特點(diǎn)包括:
????a. 這種模式下的容器沒有隔離的 network namespace;
????b. 容器的 IP 地址同Docker host 的 IP 地址;
????c. 需要注意容器中服務(wù)的端口號(hào)不能與 Docker host 上已經(jīng)使用的端口號(hào)相沖突;
????d. host 模式能夠和其它模式共存;
示意圖:
2.3 container 模式
????Container 網(wǎng)絡(luò)模式是 Docker 中一種較為特別的網(wǎng)絡(luò)的模式王带。處于這個(gè)模式下的 Docker 容器會(huì)共享其他容器的網(wǎng)絡(luò)環(huán)境,因此市殷,至少這兩個(gè)容器之間不存在網(wǎng)絡(luò)隔離愕撰,而這兩個(gè)容器又與宿主機(jī)以及除此之外其他的容器存在網(wǎng)絡(luò)隔離。??
示意圖:
????注意:因?yàn)榇藭r(shí)兩個(gè)容器要共享一個(gè)network namespace,因此需要注意端口沖突情況搞挣,否則第二個(gè)容器將無法被啟動(dòng)带迟。
2.4 none 模式
????網(wǎng)絡(luò)模式為 none,即不為 Docker 容器構(gòu)造任何網(wǎng)絡(luò)環(huán)境囱桨。一旦Docker 容器采用了none 網(wǎng)絡(luò)模式邮旷,那么容器內(nèi)部就只能使用loopback網(wǎng)絡(luò)設(shè)備婶肩,不會(huì)再有其他的網(wǎng)絡(luò)資源貌夕。Docker Container的none網(wǎng)絡(luò)模式意味著不給該容器創(chuàng)建任何網(wǎng)絡(luò)環(huán)境,容器只能使用127.0.0.1的本機(jī)網(wǎng)絡(luò)险毁。
3. 多節(jié)點(diǎn) Docker 網(wǎng)絡(luò)
????Docker 多節(jié)點(diǎn)網(wǎng)絡(luò)模式可以分為兩類们童,一類是 Docker 在 1.19 版本中引入的基于VxLAN的對(duì)跨節(jié)點(diǎn)網(wǎng)絡(luò)的原生支持;另一種是通過插件(plugin)方式引入的第三方實(shí)現(xiàn)方案慧库,比如Flannel跷跪,Calico等等。
3.1?Docker 原生overlay 網(wǎng)絡(luò)
????Docker 1.19 版本中增加了對(duì)overlay網(wǎng)絡(luò)的原生支持齐板。Docker 支持?Consul, Etcd, 和 ZooKeeper 三種分布式key-value 存儲(chǔ)吵瞻。其中,etcd?是一個(gè)高可用的分布式 k/v存儲(chǔ)系統(tǒng)甘磨,使用etcd的場(chǎng)景默認(rèn)處理的數(shù)據(jù)都是控制數(shù)據(jù)橡羞,對(duì)于應(yīng)用數(shù)據(jù),只推薦數(shù)據(jù)量很小济舆,但是更新訪問頻繁的情況卿泽。
3.1.1安裝配置
準(zhǔn)備三個(gè)節(jié)點(diǎn):
????a. devstack 192.168.1.18
????b. docker1 192.168.1.21
????c. docker2 192.168.1.19
在 devstack上使用Docker 啟動(dòng) etcd 容器:
????使用 Docker 啟動(dòng)etcd 請(qǐng)參考?https://coreos.com/etcd/docs/latest/docker_guide.html。不過滋觉,應(yīng)該是因?yàn)橹圃扃R像所使用的Dockerfile 原因签夭,官網(wǎng)上的命令因?yàn)樯倭松厦婕t色字體部分而會(huì)造成啟動(dòng)失敗:
添加紅色部分后椎瘟,容器可以被正確創(chuàng)建:
在docker1 和docker2 節(jié)點(diǎn)上修改?/etc/default/docker覆致,添加:
DOCKER_OPTS="--cluster-store=etcd://192.168.1.18:2379
--cluster-advertise=192.168.1.20:2379"
然后分別重啟 docker deamon。注意肺蔚,要使用IP地址;要是使用 hostname 的話儡羔,docker 服務(wù)將啟動(dòng)失斝颉:
root@docker2:/home/sammy# docker ps
An error occurred trying to connect: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json: read unix @->/var/run/docker.sock: read: connection reset by peer
3.1.2使用 Docker overlay 網(wǎng)絡(luò)
1)在docker1上運(yùn)行下面的命令創(chuàng)建一個(gè) overlay 網(wǎng)絡(luò)
????在 docker2 上你也會(huì)看到這個(gè)網(wǎng)絡(luò)璧诵,說明通過 etcd網(wǎng)絡(luò)數(shù)據(jù)是分布式而不是本地的了。
2)在網(wǎng)絡(luò)中創(chuàng)建容器
? ? a.在 docker2 上仇冯,運(yùn)行 docker run -d --name over2 --network overlaynet1
????????training/webapp python app.py
? ? b.在 docker1 上比被,運(yùn)行 docker run -d --name over1 --network overlaynet1
????????training/webapp python app.py
進(jìn)入容器 over2,發(fā)現(xiàn)它有兩塊網(wǎng)卡:
????其中 eth1 的網(wǎng)絡(luò)是一個(gè)內(nèi)部的網(wǎng)段尺迂,其實(shí)它走的還是普通的 NAT 模式;而 eth0 是overlay 網(wǎng)段上分配的IP地址膳音,也就是它走的是overlay 網(wǎng)絡(luò)严蓖,它的 MTU 是 1450 而不是 1500颗胡。
????進(jìn)一步查看它的路由表,你會(huì)發(fā)現(xiàn)只有同一個(gè) overlay 網(wǎng)絡(luò)中的容器之間的通信才會(huì)通過eth0弧呐,其它所有通信還是走eth1俘枫。
先看此時(shí)的網(wǎng)絡(luò)拓?fù)鋱D:
得出以下結(jié)論:
a.Docker 在每個(gè)節(jié)點(diǎn)上創(chuàng)建了兩個(gè) linux bridge,一個(gè)用于 overlay 網(wǎng)絡(luò)(ov-000100-1de98)盾舌,一個(gè)用于非 overlay 的 NAT 網(wǎng)絡(luò)(docker_gwbridge)
b.容器內(nèi)的到overlay 網(wǎng)絡(luò)的其它容器的網(wǎng)絡(luò)流量走 overlay 網(wǎng)卡(eth0),其它網(wǎng)絡(luò)流量走 NAT 網(wǎng)卡(eth1)
c.當(dāng)前Docker 創(chuàng)建vxlan 隧道的ID范圍為 256~1000膝舅,因而最多可以創(chuàng)建745個(gè)網(wǎng)絡(luò)仍稀,因此,本例中的這個(gè) vxlan 隧道使用的 ID 是256
d.Docker vxlan 驅(qū)動(dòng)使用 4789 UDP 端口
e.overlay網(wǎng)絡(luò)模型底層需要類似 consul 或 etcd 的 KV 存儲(chǔ)系統(tǒng)進(jìn)行消息同步
f.Docker overlay 不使用多播
g.Overlay 網(wǎng)絡(luò)中的容器處于一個(gè)虛擬的大二層網(wǎng)絡(luò)中
3. 網(wǎng)絡(luò)性能對(duì)比
3.1 網(wǎng)上摘錄的對(duì)比數(shù)據(jù)
1)使用 iperf 工具檢查測(cè)試了一下性能并做對(duì)比:
????兩臺(tái)主機(jī)是同一個(gè)物理機(jī)上的兩個(gè)虛機(jī),因此琉闪,結(jié)果的絕對(duì)值其實(shí)沒多少意義颠毙,相對(duì)值有一定的參考性蛀蜜。
2)文章?Testing Docker multi-host network performance?對(duì)比了多種網(wǎng)絡(luò)模式下的性能,結(jié)果如下:
3.3 關(guān)于Docker 網(wǎng)絡(luò)模式選擇的簡(jiǎn)單結(jié)論
a.Bridge 模式的性能損耗大概為10%
b.原生 overlay 模式的性能損耗非常高,甚至達(dá)到了56%幕侠,因此在生產(chǎn)環(huán)境下使用這種模式需要非常謹(jǐn)慎晤硕。
c.如果一定要使用 overlay 模式的話窗骑,可以考慮使用 Cisco 發(fā)起的? Calico 模式创译,它的性能和 bridge 相當(dāng)软族。
d.Weave overlay 模式的性能數(shù)據(jù)非常可疑颗祝,按理說應(yīng)該不可能這么差螺戳。