CNM
CNM (Container Network Model) 是 Docker 發(fā)布的容器網(wǎng)絡(luò)標(biāo)準(zhǔn)。也有不是Docker發(fā)布的標(biāo)準(zhǔn),例如CNI.CNI是由以Kubernetes為代表的公司發(fā)布的標(biāo)準(zhǔn)。主要還是因?yàn)镵ubernetes面對(duì)的是多容器而不是單容器,所以標(biāo)準(zhǔn)和docker的不一樣,有專門(mén)的博客來(lái)介紹為什么Kubernetes不選擇CNM作為容器的網(wǎng)絡(luò)標(biāo)準(zhǔn)。雖然最后k8s的CNI成為了容器網(wǎng)絡(luò)標(biāo)準(zhǔn),但是libnetwork的容器網(wǎng)絡(luò)模式使得pod中容器共享網(wǎng)絡(luò)環(huán)境成為可能。
libnetwork
Docker網(wǎng)絡(luò)部分代碼被抽離并單獨(dú)成為了Docker的網(wǎng)絡(luò)庫(kù),即libnetwork。
(圖片來(lái)自網(wǎng)絡(luò),侵刪)
從上圖可以看到libnetwork和docker daemon之間的關(guān)系。Docker daemon通過(guò)調(diào)用libnetwork對(duì)外提供的API完成網(wǎng)絡(luò)的創(chuàng)建和管理等功能。libnetwork中則使用了CNM來(lái)完成網(wǎng)絡(luò)功能的提供。同時(shí)也可以看到CNM的三個(gè)重要元素:
沙箱(sandbox):沙箱代表一個(gè)容器網(wǎng)絡(luò)棧的信息。可以對(duì)容器的接口、路由和DNS設(shè)置等進(jìn)行管理。沙盒的實(shí)現(xiàn)可以是Linux network namespace、FreeBSD Jail或者類似的機(jī)制。一個(gè)沙盒可以有多個(gè)端點(diǎn)和多個(gè)網(wǎng)絡(luò)。
接入點(diǎn)(Endpoint):接入點(diǎn)將沙箱連接到網(wǎng)絡(luò)中,代表容器的網(wǎng)絡(luò)接口,接入點(diǎn)的實(shí)現(xiàn)通常是 Linux 的 veth 設(shè)備。一個(gè)接入點(diǎn)只可以屬于一個(gè)網(wǎng)絡(luò)并且只屬于一個(gè)沙箱。
網(wǎng)絡(luò)(Network):網(wǎng)絡(luò)是一組可以直接互相聯(lián)通的接入點(diǎn)。網(wǎng)絡(luò)的實(shí)現(xiàn)可以是Linux bridge、VLAN等。它將多接入點(diǎn)組成一個(gè)子網(wǎng),并且多個(gè)接入點(diǎn)之間可以相互通信。
了解了CNM,接下來(lái)我們來(lái)認(rèn)識(shí)libnetwork的四種常見(jiàn)網(wǎng)絡(luò)模式:
- null 空網(wǎng)絡(luò)模式:可以幫助我們構(gòu)建一個(gè)沒(méi)有網(wǎng)絡(luò)接入的容器環(huán)境,以保障數(shù)據(jù)安全。
- bridge 橋接模式:可以打通容器與容器間網(wǎng)絡(luò)通信的需求。
- host 主機(jī)網(wǎng)絡(luò)模式:可以讓容器內(nèi)的進(jìn)程共享主機(jī)網(wǎng)絡(luò),從而監(jiān)聽(tīng)或修改主機(jī)網(wǎng)絡(luò)。
- container 網(wǎng)絡(luò)模式:可以將兩個(gè)容器放在同一個(gè)網(wǎng)絡(luò)命名空間內(nèi),讓兩個(gè)業(yè)務(wù)通過(guò) localhost 即可實(shí)現(xiàn)訪問(wèn)。
(1)null 空網(wǎng)絡(luò)模式
空網(wǎng)意味著沒(méi)有網(wǎng)絡(luò)信息,就是一個(gè)單純的沒(méi)有連接網(wǎng)絡(luò)的一個(gè)容器。我們可以使用docker命令來(lái)創(chuàng)建一個(gè)空網(wǎng)模式的容器來(lái)檢查容器內(nèi)部的網(wǎng)絡(luò)信息,首先我們可以先打開(kāi)正常模式的容器來(lái)看一下網(wǎng)絡(luò)信息:
/yapi # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:12:00:02
inet addr:172.18.0.2 Bcast:172.18.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:597521 errors:0 dropped:0 overruns:0 frame:0
TX packets:1194752 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:126660347 (120.7 MiB) TX bytes:254347460 (242.5 MiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:38 errors:0 dropped:0 overruns:0 frame:0
TX packets:38 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2362 (2.3 KiB) TX bytes:2362 (2.3 KiB)
/yapi # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.18.0.1 0.0.0.0 UG 0 0 0 eth0
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
可以看到里面是有網(wǎng)卡信息eth0,ip也正常展示。接下來(lái)我們新建空網(wǎng)模式的容器,再來(lái)觀察它的網(wǎng)卡信息和路由信息:
[root@VM-12-13-centos ~]# docker run --net=none -it busybox
/ # ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
/ #
可以看到,新建的容器沒(méi)有eth0的信息,并且沒(méi)有ip信息。這種模式如果不進(jìn)行特定的配置是無(wú)法正常使用的,但是優(yōu)點(diǎn)也非常明顯,它給了用戶最大的自由度來(lái)自定義容器的網(wǎng)絡(luò)環(huán)境。
(2)bridge 橋接模式
bridge橋接模式是Docker網(wǎng)絡(luò)模型中的一種常見(jiàn)網(wǎng)絡(luò)模式,它可以讓多個(gè)容器之間相互通信,也可以與外部網(wǎng)絡(luò)進(jìn)行通信。在bridge模式下,每個(gè)容器都會(huì)分配一個(gè)唯一的IP地址,并且可以通過(guò)容器名稱或者IP地址互相訪問(wèn)。我們先來(lái)了解關(guān)于Docker的bridge模式的實(shí)現(xiàn)原理。
linux veth 和linux bridge
(圖片來(lái)自網(wǎng)絡(luò),侵刪)
docker 的bridge模式就是這樣的,可以看到docker0像一個(gè)交換機(jī),把不同的容器連通,是他們可以互相通信。一般我們?cè)谑褂胐ocker做網(wǎng)絡(luò)映射時(shí),通常都加了-p指定端口,用來(lái)做容器間的通信或者與容器外部通信。
(3)host 主機(jī)網(wǎng)絡(luò)模式
host 主機(jī)網(wǎng)絡(luò)模式讓容器內(nèi)的進(jìn)程共享主機(jī)的網(wǎng)絡(luò)棧,從而使得容器內(nèi)的應(yīng)用程序能夠直接與主機(jī)和外部網(wǎng)絡(luò)進(jìn)行通信,同時(shí)也可以避免了端口映射和NAT等額外的網(wǎng)絡(luò)開(kāi)銷(xiāo)。使用這種模式的時(shí)候,libnetwork并不會(huì)創(chuàng)建獨(dú)立的network namespace。同樣,我們查看host模式下容器內(nèi)部的網(wǎng)絡(luò)信息
[root@VM-12-13-centos ~]# docker run -it --net=host busybox
/ # ip a
1: lo: mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc mq qlen 1000
link/ether 52:54:00:4f:76:46 brd ff:ff:ff:ff:ff:ff
inet 10.0.12.13/22 brd 10.0.15.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe4f:7646/64 scope link
valid_lft forever preferred_lft forever
3: br-85f2d3e30fa7: mtu 1500 qdisc noqueue
link/ether 02:42:3e:54:35:a5 brd ff:ff:ff:ff:ff:ff
inet 172.22.0.1/16 brd 172.22.255.255 scope global br-85f2d3e30fa7
valid_lft forever preferred_lft forever
4: br-c42d4a549c65: mtu 1500 qdisc noqueue
link/ether 02:42:39:a3:4a:26 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-c42d4a549c65
valid_lft forever preferred_lft forever
inet6 fe80::42:39ff:fea3:4a26/64 scope link
valid_lft forever preferred_lft forever
5: docker0: mtu 1500 qdisc noqueue
link/ether 02:42:fd:43:ed:84 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:fdff:fe43:ed84/64 scope link
valid_lft forever preferred_lft forever
6: br-f057a92711b7: mtu 1500 qdisc noqueue
link/ether 02:42:78:b5:0a:b4 brd ff:ff:ff:ff:ff:ff
inet 172.21.0.1/16 brd 172.21.255.255 scope global br-f057a92711b7
valid_lft forever preferred_lft forever
/ #
可以看到容器內(nèi)的網(wǎng)絡(luò)環(huán)境與主機(jī)完全一致。但是,但是,容器其他方面,如文件系統(tǒng)、進(jìn)程列表等還是和宿主機(jī)隔離的。所以如果是集群規(guī)模比較大的情況,還是不是用這種host模式的。
(4)container 網(wǎng)絡(luò)模式
container 網(wǎng)絡(luò)模式可以將多個(gè)容器放在同一個(gè)網(wǎng)絡(luò)命名空間內(nèi)。當(dāng)這些容器需要共享網(wǎng)絡(luò),但其他資源仍然需要隔離時(shí)就可以使用 container 網(wǎng)絡(luò)模式,例如我們開(kāi)發(fā)了一個(gè) http 服務(wù),但又想使用 nginx 的一些特性,讓 nginx 代理外部的請(qǐng)求然后轉(zhuǎn)發(fā)給自己的業(yè)務(wù),這時(shí)我們使用 container 網(wǎng)絡(luò)模式將自己開(kāi)發(fā)的服務(wù)和 nginx 服務(wù)部署到同一個(gè)網(wǎng)絡(luò)命名空間中。
當(dāng)創(chuàng)建一個(gè)新容器時(shí),我們可以使用以下命令將其加入到已存在的網(wǎng)絡(luò)命名空間:
docker run -d --name my-nginx1 nginx
docker run -d --name my-nginx2 --network container:my-nginx1 nginx
通過(guò)上述命令,我們可以在my-nginx2容器中通過(guò) curl http://localhost來(lái)訪問(wèn)my-nginx1容器的Web服務(wù)。在container模式下,所有的容器都共享同一個(gè)網(wǎng)絡(luò)棧和IP地址,因此它們之間的網(wǎng)絡(luò)性能通常比bridge模式更高,但安全性可能會(huì)降低。
總結(jié):
- Docker使用CNM為通信標(biāo)準(zhǔn)來(lái)完成網(wǎng)絡(luò)實(shí)現(xiàn);
- CNM三要素:沙箱(Sandbox)、接入點(diǎn)(Endpoint)、網(wǎng)絡(luò)(Network);
- Libnetwork 常見(jiàn)四種網(wǎng)絡(luò)模式:null 空網(wǎng)絡(luò)模式、bridge 橋接模式、host 主機(jī)網(wǎng)絡(luò)模式、container 網(wǎng)絡(luò)模式;
-
freebsd
+關(guān)注
關(guān)注
0文章
37瀏覽量
10766 -
VLAN技術(shù)
+關(guān)注
關(guān)注
0文章
45瀏覽量
6378 -
LINUX內(nèi)核
+關(guān)注
關(guān)注
1文章
316瀏覽量
21619
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論