1. 簡介
單主機的四種網絡模式:
- bridge 模式,使用–network=bridge指定,不支持多主機;(默認)
- host 模式,使用–network=host指定,不支持多主機;
- container 模式,使用–network=container:NAME_or_ID指定,即joiner 容器,不支持多主機;
- none 模式,使用–network=none指定,不支持多主機。
補充:
容器間的通信:
- 單主機的容器間通信;
- 跨主機的容器間通信。
2. bridge模式
bridge模式是 docker 的默認網絡模式,不寫–net參數,就是bridge模式。
2.1 bridge之使用默認網橋
當Docker進程啓動時,會在主機上創建一個名爲docker0的虛擬網橋,此主機上啓動的Docker容器會連接到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網絡中。從docker0子網中分配一個 IP 給容器使用,並設置 docker0 的 IP 地址爲容器的默認網關。
在主機上創建一對虛擬網卡veth pair設備,Docker 將 veth pair 設備的一端放在新創建的容器中,並命名爲eth0(容器的網卡),另一端放在主機中,以vethxxx這樣類似的名字命名,並將這個網絡設備加入到 docker0 網橋中。可以通過brctl show命令查看。安裝brctl命令:
[root@linux-node4 ~]# yum install -y bridge-utils
[root@linux-node4 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242d84b7159 no
使用docker run -p時,docker 實際是在iptables做了DNAT規則,實現端口轉發功能。可以使用iptables -t nat -vnL查看。bridge模式如下圖所示:
(補充:iptables相當於防火牆)
驗證過程如下:
-
步驟一:創建兩個容器
$ docker run --name docker1 nginx:1.13.12 $ docker run -d --name docker2 nginx:1.13.12
-
步驟二:查看機器上多了兩個veth虛擬網卡,查看網絡地址如我們之前說的一樣
[root@linux-node4 ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242d84b7159 no veth8c72f4a vethf15e034 [root@linux-node4 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 75539117a127 nginx:1.13.12 "nginx -g 'daemon of…" About an hour ago Up About an hour 80/tcp docker2 69f1c16d206c nginx:1.13.12 "nginx -g 'daemon of…" About an hour ago Up About an hour 80/tcp docker1 [root@linux-node4 ~]# docker inspect 75539117a127 |grep 172.17 "Gateway": "172.17.0.1", "IPAddress": "172.17.0.3", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.3",
2.2 bridge之使用自定義網橋
- 創建一個自定義網橋:
# -d指定模式爲bridge,也可以爲overlay
# --subnet指定子網範圍
$ docker network create -d bridge my-net4 --subnet=192.168.100.1/24
- 創建兩個容器,並連接到我們自建的網橋:
[root@linux-node4 ~]# docker run -d --name=my_test1 --network my-net4 nginx:1.13.12
ffc47de3992c52730ff2590b4b3903fe737521b9c713170d19b747fa2941c8b1
- 查看容器的網絡地址,驗證其ip地址是否是我們自定義的網絡。
[root@linux-node4 ~]# docker inspect ffc47de3992 |grep 192
"Gateway": "192.168.100.1",
"IPAddress": "192.168.100.2",
(注意:同一個網橋內的網絡是相互可以通信的,本篇不做過多說明。)
3. host模式
如果啓動容器的時候使用host模式,那麼這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個 Network Namespace。容器將不會虛擬出自己的網卡,配置自己的 IP 等,而是使用宿主機的 IP 和端口。但是,容器的其他方面,如文件系統、進程列表等還是和宿主機隔離的。 Host模式如下圖所示:
驗證過程如下:
-
創建一個網絡類型爲host的容器:
$ docker run -d --net=host --name=my_host1 nginx:1.13.12
-
因爲nginx容器本身的端口號是80,所以我們直接使用本地的接口來訪問宿主機的ip和端口號。
[root@linux-node4 ~]# !curl curl http://127.0.0.1:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
(注意:使用host模式的時候,不要一個容器啓動多個實例,會引起端口衝突導致容器啓動失敗,這種網絡模型是無法使用nat轉化的)
host模式的缺點:
-
容器沒有隔離、獨立的網絡棧:容器因爲與宿主機共享網絡而爭搶資源,並且容易崩潰也可能導致主機崩潰,這在生產環境是不允許發生的;
-
端口資源:docker host上已經使用的端口就不能再使用了
host模式的優點:
- 可以直接使用宿主機ip與外界通信,無需額外進行nat轉換,由於容器與外部通信,不再需要使用bridge等方式轉發或者進行數據包的封裝,性能上有很大優勢。
4. container模式
這個模式指定新創建的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享。新創建的容器不會創建自己的網卡,配置自己的 IP,而是和一個指定的容器共享 IP、端口範圍等。同樣,兩個容器除了網絡方面,其他的如文件系統、進程列表等還是隔離的。兩個容器的進程可以通過 lo 網卡設備通信。 Container模式示意圖:
驗證過程如下:
- 上文我們已經創建了一個自定義網橋的容器,鏈接到這個容器裏面即可
[root@linux-node4 ~]# docker run -d --name docker_con3 --net=container:ffc47de3992c busybox sleep 6000
933dd7fce1a67883869a6235c3a4f7835c983e079592087734715d05f6bd755e
- 進入容器內部驗證網絡是否跟預期一致:
[root@linux-node4 ~]# docker exec -it 933dd7fce1a6 sh
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
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
33: eth0@if34: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:64:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.2/24 brd 192.168.100.255 scope global eth0
valid_lft forever preferred_lft forever
/ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.100.1 0.0.0.0 UG 0 0 0 eth0
192.168.100.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
5. None模式
使用none模式,Docker 容器擁有自己的 Network Namespace,但是,並不爲Docker 容器進行任何網絡配置。也就是說,這個 Docker 容器沒有網卡、IP、路由等信息。需要我們自己爲 Docker 容器添加網卡、配置 IP 等。 None模式示意圖:
[root@linux-node4 ~]# docker run -d --net=none --name docker_none2 busybox sleep 6000
247fb9eace8b5dedcb47b7f2015eb06f18d4eb67eb323560dcfaaf7ef1069773
網絡情況驗證:
[root@linux-node4 ~]# docker exec -it 247fb9eace8b /bin/sh
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
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
/ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
/ #
參考地址,文章略有改動: