Docker容器網絡
1、Docker容器網絡
Docker在安裝後自動提供3種網絡,可以使用``docker network ls`指令檢視
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
76170d3f9538 bridge bridge local
38bb8b947433 host host local
c74fce351c8a none null local
Docker使用Linux橋接,在主控端虛拟一個Docker容器網橋(docker0),Docker啟動一個容器時會根據Docker網橋的網段配置設定給容器一個IP位址,稱為Container-IP,同時Docker網橋是每個容器的預設網關。因為在同一主控端内的容器都接入同一個網橋,這樣容器之間就能夠通過容器的Container-IP直接通信。
Docker 網絡管理指令
docker network connect #将容器連接配接到指定的網絡
docker network create #建立一個網絡
docker network disconnect #斷開容器與指定網絡的連接配接
docker network inspect #顯示一個或多個網絡的詳細資訊
docker network ls #顯示網絡清單
docker networkprune #删除所有未使用的網絡
docker network rm #删除一個或多個網絡
2、Docker的四種網絡模式
網絡模式 | 配置 | 說明 |
---|---|---|
host | --network host | 容器和主控端共享Network namespace |
container | --network container:NAME_OR_ID | 容器和另外一個容器共享Network namespace |
none | --network none | 容器有獨立的Network namespace, 但并沒有對其進行任何網絡設定, 如配置設定veth pair 和網橋連接配接,配置IP等 |
bridge | --network bridge | 預設模式 |
# 使用busybox鏡像建立容器web1
[root@localhost ~]# docker run -dit --name web1 busybox
3f96ace9c63f2863ca0c81ce8f933e2f0099c9a4902a8f4b4f4a111c9306e7ea
# 檢視主機ip位址
[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:bb:22:82 brd ff:ff:ff:ff:ff:ff
inet 192.168.111.135/24 brd 192.168.111.255 scope global dynamic noprefixroute ens160
valid_lft 1221sec preferred_lft 1221sec
inet6 fe80::3d5c:b9d6:55f:48e9/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:f0:ef:67:fd 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:f0ff:feef:67fd/64 scope link
valid_lft forever preferred_lft forever
5: vethdd490f4@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 0e:34:3e:de:8d:11 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::c34:3eff:fede:8d11/64 scope link
valid_lft forever preferred_lft forever
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuYDO2IDMzkDO00SMzYzMxgTM0EDMxgDMyIDMy0SNykDOzkjMvwFOwIjMwIzLcVjM5gzM5IzLcd2bsJ2Lc12bj5ycn9Gbi52YuIjMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
2.1 bridge模式
當Docker程序啟動時,會在主機上建立一個名為docker0的虛拟網橋,此主機上啟動的Docker容器會連接配接到這個虛拟網橋上。虛拟網橋的工作方式和實體交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網絡中。
從docker0子網中配置設定一個IP給容器使用,并設定docker0的IP位址為容器的預設網關。在主機上建立一對虛拟網卡veth pair裝置,Docker将veth pair裝置的一端放在新建立的容器中,并命名為eth0(容器的網卡),另一端放在主機中,以vethxxx這樣類似的名字命名,并将這個網絡裝置加入到docker0網橋中。可以通過
brctl show
指令檢視。
bridge模式是docker的預設網絡模式,不寫--network參數,就是bridge模式。使用docker run -p時,docker實際是在iptables做了DNAT規則,實作端口轉發功能。可以使用
iptables -t nat -vnL
檢視。
bridge模式如下圖所示:
假設上圖的docker2中運作了一個nginx,大家來想幾個問題:
- 同主機間兩個容器間是否可以直接通信?比如在docker1上能不能直接通路到docker2的nginx站點?
- 在主控端上能否直接通路到docker2的nginx站點?
- 在另一台主機上如何通路node1上的這個nginx站點呢?DNAT釋出?
Docker網橋是主控端虛拟出來的,并不是真實存在的網絡裝置,外部網絡是無法尋址到的,這也意味着外部網絡無法通過直接Container-IP通路到容器。如果容器希望外部通路能夠通路到,可以通過映射容器端口到宿主主機(端口映射),即docker run建立容器時候通過 -p 或 -P 參數來啟用,通路容器的時候就通過[主控端IP]:[容器端口]通路容器。
# bridge模式
[root@localhost ~]# docker run -it --rm busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.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 172.17.0.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
(另起一個終端)
# 在使用互動模式進去進入busybox
[root@localhost ~]# docker run -it --rm busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.3/16 brd 172.17.255.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 172.17.0.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
# ping另一個(172.17.0.2)測試是否連通
/ # ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.201 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.127 ms
^C
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.127/0.164/0.201 ms
# ping主機(172.17.0.1)測試是否連通
/ # ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: seq=0 ttl=64 time=0.125 ms
64 bytes from 172.17.0.1: seq=1 ttl=64 time=0.096 ms
^C
--- 172.17.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.096/0.110/0.125 ms
2.2 container模式
這個模式指定新建立的容器和已經存在的一個容器共享一個 Network Namespace,而不是和主控端共享。新建立的容器不會建立自己的網卡,配置自己的 IP,而是和一個指定的容器共享 IP、端口範圍等。同樣,兩個容器除了網絡方面,其他的如檔案系統、程序清單等還是隔離的。兩個容器的程序可以通過 lo 網卡裝置通信。
container模式如下圖所示:
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8293af30d1da busybox "sh" 5 seconds ago Up 4 seconds web1
# container模式
[root@localhost ~]# docker run -it --rm --network container:web1 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
2.3 host模式
如果啟動容器的時候使用host模式,那麼這個容器将不會獲得一個獨立的Network Namespace,而是和主控端共用一個Network Namespace。容器将不會虛拟出自己的網卡,配置自己的IP等,而是使用主控端的IP和端口。但是,容器的其他方面,如檔案系統、程序清單等還是和主控端隔離的。
使用host模式的容器可以直接使用主控端的IP位址與外界通信,容器内部的服務端口也可以使用主控端的端口,不需要進行NAT,host最大的優勢就是網絡性能比較好,但是docker host上已經使用的端口就不能再用了,網絡的隔離性不好。
Host模式如下圖所示:
# 容器和主控端共享Network namespace
[root@localhost ~]# docker run -it --rm --network host busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel qlen 1000
link/ether 00:0c:29:bb:22:82 brd ff:ff:ff:ff:ff:ff
inet 192.168.111.135/24 brd 192.168.111.255 scope global dynamic noprefixroute ens160
valid_lft 1031sec preferred_lft 1031sec
inet6 fe80::3d5c:b9d6:55f:48e9/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
link/ether 02:42:f0:ef:67:fd 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:f0ff:feef:67fd/64 scope link
valid_lft forever preferred_lft forever
13: vethd4e59b4@if12: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master docker0
link/ether de:9f:8a:68:b6:fc brd ff:ff:ff:ff:ff:ff
inet6 fe80::dc9f:8aff:fe68:b6fc/64 scope link
valid_lft forever preferred_lft forever
2.4 none模式
使用none模式,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進行任何網絡配置。也就是說,這個Docker容器沒有網卡、IP、路由等資訊。需要我們自己為Docker容器添加網卡、配置IP等。
這種網絡模式下容器隻有lo回環網絡,沒有其他網卡。none模式可以在容器建立時通過--network none來指定。這種類型的網絡沒有辦法聯網,封閉的網絡能很好的保證容器的安全性。
應用場景:
- 啟動一個容器處理資料,比如轉換資料格式
- 一些背景的計算和處理任務
none模式如下圖所示:
# none模式
[root@localhost ~]# docker run -it --rm --network none busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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
檢視bridge網絡的詳細配置
[root@localhost ~]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "76170d3f9538f2d278789de3ea3bfa310db6e605a00e1615d453d083f6ad0c8b",
"Created": "2022-08-09T20:26:03.696604937+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]