標(biāo)準(zhǔn)的Docker支持4類(lèi)網(wǎng)絡(luò)模式
- host模式:容器和宿主機(jī)共享Network namespace。
- container模式: 容器和另外一個(gè)容器共享Network namespace。
- none模式:容器有獨(dú)立的Network namespace,但并沒(méi)有對(duì)其進(jìn)行任何網(wǎng)絡(luò)設(shè)置,如分配veth pair 和網(wǎng)橋連接,配置IP等。
- bridge模式:docker默認(rèn)模式,就是利用在Docker網(wǎng)絡(luò)學(xué)習(xí)第一篇-Linux虛擬網(wǎng)絡(luò)講到的Birdge實(shí)現(xiàn)。
host模式
就是和主機(jī)使用同一個(gè)network namespace, 直接使用主機(jī)的ip和端口與外界通信。下面通過(guò)nginx演示,在nginx-conf/default.conf 配置文件中指定端口為11111
docker run --rm --name nginx-test --net=host -v /data/ljgeng/nginx-conf:/etc/nginx/conf.d nginx
另起一個(gè)窗口,輸入命令curl -I localhost:11111
, 可以看到返回響應(yīng)碼200,說(shuō)明訪(fǎng)問(wèn)是成功的。nginx-test 并沒(méi)有指定任何端口映射,容器中的11111
端口實(shí)際就是主機(jī)端口,從表現(xiàn)的現(xiàn)象來(lái)看,確實(shí)可以直接使用了主機(jī)ip和端口和nginx-test通信,要進(jìn)一步驗(yàn)證nginx-test和主機(jī)是使用同一個(gè)network namespace,首先得了解下面這個(gè)知識(shí):
不同network namespace中的進(jìn)程有不同的net:[]號(hào)碼發(fā)配,擁有相同net:[]號(hào)碼的進(jìn)程屬于同一個(gè)network namesapce
- 首先查看nginx-test進(jìn)程號(hào)
docker inspect nginx-test -f "{{.State.Pid}}"
16705
- 查看 nginx-test的 net 號(hào)
ll /proc/16705/ns
...
lrwxrwxrwx 1 root root 0 Aug 17 11:03 net -> net:[4026531956]
...
- 查看 主機(jī)的net號(hào)
ll /proc/self/ns
...
lrwxrwxrwx 1 root root 0 Aug 17 11:18 net -> net:[4026531956]
...
可以看出nginx-test與主機(jī)net號(hào)確實(shí)相同,說(shuō)明使用了同一個(gè)network namespace, 模式示例圖如下:
container模式
和host不同的是,容器和另一個(gè)容器共享namespace。兩個(gè)容器的進(jìn)程可以通過(guò) lo 網(wǎng)卡設(shè)備通信,現(xiàn)有兩個(gè)容器, nginx-test 和 nginx-test1, 后者與前者共享network namespace,前者端口設(shè)置為11111, 后者為11112。
- 窗口1執(zhí)行
docker run --rm --name nginx-test -v /data/ljgeng/nginx-conf:/etc/nginx/conf.d nginx
- 窗口2執(zhí)行
docker run --rm --name nginx-test1 \
--net=container:nginx-test -v /data/ljgeng/nginx-conf1:/etc/nginx/conf.d nginx
- 窗口3執(zhí)行
docker exec -it nginx-test1 /bin/sh -c "apt-get update && apt install curl && curl -I localhost:11111"
...
HTTP/1.1 200 OK
...
none模式
通過(guò)--network=none來(lái)指定。這種類(lèi)型的網(wǎng)絡(luò)沒(méi)有辦法聯(lián)網(wǎng),封閉的網(wǎng)絡(luò)可以很好的保證容器的安全性。
bridge模式
在Docker進(jìn)程啟動(dòng)時(shí)會(huì)自動(dòng)創(chuàng)建一個(gè)虛擬網(wǎng)橋 docker0, 在創(chuàng)建某一個(gè)具體的容器時(shí),如果沒(méi)有指定--net 或者指定--net=bridge, 那么在創(chuàng)建容器的同時(shí)會(huì)創(chuàng)建一對(duì)veth pair 設(shè)備,一端放在容器中,一端接入網(wǎng)橋docker0上。
通過(guò)brctl show
查看 網(wǎng)橋設(shè)備
[root@2030-edu-01-no ~]# brctl show
bridge name bridge id STP enabled interfaces
br-40a246442710 8000.024299092001 no
docker0 8000.0242612d67e0 no veth0734eff
...
在啟動(dòng)容器時(shí) 通過(guò)-p port:port
指定映射端口,實(shí)際是利用DANT進(jìn)行的轉(zhuǎn)發(fā),DNAT知識(shí)可以在Docker網(wǎng)絡(luò)學(xué)習(xí)第二篇-認(rèn)識(shí)iptables 查看。使用iptables -t nat -vnL
查看轉(zhuǎn)發(fā)規(guī)則。
使用docker network create <network-name>
(可以使用-d 指定驅(qū)動(dòng),默認(rèn)是bridge) 命令時(shí),實(shí)際就是創(chuàng)建了一個(gè)網(wǎng)橋,同一個(gè)網(wǎng)橋內(nèi)的容器可以互相通信;
使用ip netns ls 查看時(shí),并沒(méi)有發(fā)現(xiàn)docker容器的namespace, 這是因?yàn)閐ocker啟動(dòng)容器后會(huì)以進(jìn)程號(hào)創(chuàng)建新的名字空間,而在較新的版本里面,默認(rèn)刪除了系統(tǒng)中的名字空間信息文件,如果想恢復(fù),只需要執(zhí)行
ln -s /proc/容器進(jìn)程號(hào)/ns/net /var/run/netns/容器
命令即可。