在討論其他網(wǎng)絡(luò)驅(qū)動之前皮获,我們先了解一下docker網(wǎng)絡(luò)底層用到的技術(shù)。
linux網(wǎng)絡(luò)基礎(chǔ)
??? docker網(wǎng)絡(luò)底層采用Linux內(nèi)核的網(wǎng)絡(luò)棧蝴乔。為了實(shí)現(xiàn)CNM網(wǎng)絡(luò)驅(qū)動挣棕,dockers用到了Linux bridge、network namespace固惯、veth pairs和iptables梆造。
The Linux Bridge
??? Linux bridge是一個(gè)2層的設(shè)備,是物理交換機(jī)在Linux內(nèi)核的虛擬實(shí)現(xiàn)葬毫。它基于MAC地址轉(zhuǎn)發(fā)網(wǎng)絡(luò)流量镇辉。
??? Linux bridge在docker網(wǎng)絡(luò)驅(qū)動中被廣泛應(yīng)用,但是和docker 網(wǎng)絡(luò)驅(qū)動中的bridge不同贴捡,后者是在Linux bridge更高一層的實(shí)現(xiàn)忽肛。
Network Namespaces
??? network namespace?在內(nèi)核中擁有一個(gè)單獨(dú)的網(wǎng)絡(luò)棧,它有自己的接口烂斋、路由和防火墻規(guī)則屹逛。
??? 它可用于隔離容器container。除非通過docker network做了相關(guān)配置汛骂,否則Network namespace可以確保在同一主機(jī)的兩個(gè)容器間無法相互通信罕模,即使和主機(jī)本身也無法通信。一種典型情況是CNM網(wǎng)絡(luò)驅(qū)動為每一個(gè)container使用不同的namespace香缺。另外手销,容器container也可以共享同一個(gè)network namespace,哪怕是主機(jī)network namespace的一部分
Virtual Ethernet Devices
??? Veth(virtual ethernet device)是Linux網(wǎng)絡(luò)接口图张,它用于連接兩個(gè)network namespace锋拖。當(dāng)創(chuàng)建docker網(wǎng)絡(luò)時(shí)诈悍,Docker網(wǎng)絡(luò)驅(qū)動使用veth提供namespace間的顯式連接。在container被附加到一個(gè)docker網(wǎng)絡(luò)后兽埃,veth的一端被放置入container內(nèi)侥钳,另一端被附加到dockers網(wǎng)絡(luò)。
iptables
??? iptables?作為Linux內(nèi)核的一部分用于本地的包過濾柄错,類似工作于第三和第四層的防火墻舷夺。它在docker的本地網(wǎng)絡(luò)驅(qū)動的被廣泛使用。
Host Network Driver
Host網(wǎng)絡(luò)驅(qū)動 和Linux主機(jī)的網(wǎng)絡(luò)配置一樣售貌。?--net=host?將關(guān)閉docker網(wǎng)絡(luò)给猾,并且container使用主機(jī)OS的網(wǎng)絡(luò)棧。如果使用其它網(wǎng)絡(luò)驅(qū)動颂跨,每個(gè)container將被置于自己的network namespace以實(shí)現(xiàn)彼此的網(wǎng)絡(luò)隔離敢伸。
使用host驅(qū)動,所有的container都處于同一個(gè)主機(jī)network namespace內(nèi)恒削,并且使用主機(jī)的網(wǎng)絡(luò)接口和IP協(xié)議棧池颈。在這種情況下,所有的container都可以在主機(jī)接口上相互通信钓丰。因?yàn)樗腥萜魇褂孟嗤闹鳈C(jī)接口躯砰,所有兩個(gè)container不能綁定到同一個(gè)TCP端口,這有可能會導(dǎo)致端口爭用携丁。
示例:
主機(jī)網(wǎng)絡(luò)
?# ip a|grep enp2s0
2: enp2s0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
inet192.168.10.9/24 brd 192.168.10.255 scope global enp2s0
兩個(gè)container網(wǎng)絡(luò)
# docker run --name=C1--net=hostbusybox ip a|grep enp2s0
2: enp2s0: mtu 1500 qdisc pfifo_fast qlen 1000
??? inet 192.168.10.9/24brd 192.168.10.255 scope global enp2s0
# docker run --name=C2--net=hostbusybox ip a|grep enp2s0
2: enp2s0: mtu 1500 qdisc pfifo_fast qlen 1000
inet 192.168.10.9/24 brd 192.168.10.255 scopeglobal enp2s0
在本例中琢歇,當(dāng)container使用host網(wǎng)絡(luò)時(shí),主機(jī)梦鉴、C1和C2共用一個(gè)接口enp2s0 矿微。
使用host驅(qū)動,dockers不再管理容器container的網(wǎng)絡(luò)棧尚揣,比如端口映射或者路由規(guī)則。網(wǎng)絡(luò)流量直接從容器進(jìn)入主機(jī)接口掖举,這也使得host網(wǎng)絡(luò)成為最簡單和延遲最低的網(wǎng)絡(luò)驅(qū)動快骗。
None network driver
1.? None網(wǎng)絡(luò)驅(qū)動和host網(wǎng)絡(luò)驅(qū)動相似,Dockers engine不會在容器container內(nèi)部創(chuàng)建接口塔次、端口映射或者路由方篮。
2.? 和host 驅(qū)動不同的是none?驅(qū)動為每一個(gè)container創(chuàng)建了一個(gè)獨(dú)立的namespace。這保證了container網(wǎng)絡(luò)與其它c(diǎn)ontainer或者主機(jī)的隔離励负。
3.?? 使用--net=none創(chuàng)建的container和其它容器和主機(jī)完全隔離藕溅。
4.?? 容器內(nèi)部除了lookback接口外再也沒有其它接口。
# docker run --name=C3 --net=none busybox ip a?? ??
1: lo: mtu 65536 qdisc noqueue qlen1
??? link/loopback00:00:00:00:00:00 brd 00:00:00:00:00:00
??? inet 127.0.0.1/8 scopehost lo
?????? valid_lft foreverpreferred_lft forever
5.? 使用--net=none?或者?--net=host?的容器無法連接到其它的dockers網(wǎng)絡(luò)继榆。