1. Docker網絡模式
Docker在創建容器時有四種網絡模式,bridge爲默認不需要用--net=bridge去指定,其他三種模式需要在創建容器時使用--net去指定。
Docker安裝後,會自動創建三個網絡,分別爲bridge、host、none。可以使用以下命令查看:
ycy@ubuntu18:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
349d6173c6e8 bridge bridge local
738ff1fb9923 host host local
1abb3c2c9846 none null local
1.1 bridge模式
默認情況下,創建一個新的容器都會自動連接到bridge網絡,相當於Vmware中的Nat模式。
新建容器有獨立的網絡命名空間,並通過以下步驟將容器接入docker0中。
(1)創建veth pari虛擬網絡對(類似於網線的兩頭);
(2)將veth pair的一端置於主機的root network namespace中,並將其關聯docker0;
(3)將veth pair的另一端置於新建容器的網絡命名空間中;
(4)從docker0所在的子網中選一個可用的IP地址賦予veth pair在容器的一端。
ycy@ubuntu18:~$ docker run -d --name s1 nginx
f5e8a999d00b06d9d95ecf732c81fbf1ff6b29b5707ed0868304d7c40567cd80
ycy@ubuntu18:~$ docker inspect -f "{{ .NetworkSettings.IPAddress }}" s1
172.17.0.2
ycy@ubuntu18:~$ brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.02422bc4b451 no veth392e4b4
1.2 host模式
相當於Vmware中的橋接模式。新建容器與宿主機共享網絡命名空間,該容器不會連接到docker0中,直接使用網絡的網絡資源進行通信。
ycy@ubuntu18:~$ docker run -it --name v1 --network host nginx /bin/bash
root@ubuntu18:/# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:2bff:fec4:b451 prefixlen 64 scopeid 0x20<link>
ether 02:42:2b:c4:b4:51 txqueuelen 0 (Ethernet)
RX packets 25018 bytes 1093724 (1.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 30033 bytes 185103642 (176.5 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.146.100 netmask 255.255.255.0 broadcast 192.168.146.255
inet6 fe80::badd:42b1:f38b:bf0f prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:9e:08:65 txqueuelen 1000 (Ethernet)
RX packets 231221 bytes 282634477 (269.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 72539 bytes 6474630 (6.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 6118 bytes 534681 (522.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 6118 bytes 534681 (522.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
1.3 none模式
新建容器有獨立的網絡namespace,但是不會配置任何網絡參數,也不會接入docker0中,用戶可對其進行任意的手動配置。
ycy@ubuntu18:~$ docker run -it --name net-none --network none mynginx /bin/bash
root@65fed235fdcb:/# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
1.4 container模式
新建容器與一個已有的容器共享network namespace,該容器不會連接到docker0中,直接使用已有容器的網絡資源進行通信。
joined容器是一種較爲特別的網絡模式
在容器創建時使用--network=container:name(name是運行的容器名)
處在這個模式下的Docker容器會共享一個網絡棧,這樣兩個容器可以使用localhost高效快速通信。
ycy@ubuntu18:~$ docker run -it --name s1 mynginx /bin/bash
root@da6f3ecc0391:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 21 bytes 2682 (2.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@da6f3ecc0391:/# ycy@ubuntu18:~$
ycy@ubuntu18:~$ docker run -it --name s2 --network container:s1 mynginx /bin/bash
root@da6f3ecc0391:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 25 bytes 3036 (2.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
1.5 用戶自定義網絡模式
Docker提供了三種自定義網絡驅動:bridge、overlay、macvlan。
bridge驅動類似於默認的bridge網絡模式,但增加了一些新的功能(帶DNS解析功能),overllay和macvlan適用於創建跨主機網絡。
創建橋接網絡
ycy@ubuntu18:~$ docker network create -d bridge --subnet 172.20.0.0/24 --gateway 172.20.0.1 br0
a765c3af4c5220534638e542d8dfa10e45e0e89c6d6f83820d0232339b35e3c7
創建bridge網絡後,可以看到新增了一個網橋(172.20.0.1)。
ycy@ubuntu18:~$ ip a | grep br-
19: br-a765c3af4c52: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
inet 172.20.0.1/24 brd 172.20.0.255 scope global br-a765c3af4c52
2. Docker網絡通信
2.1 同一宿主機不同網橋間的容器間的通信
創建兩個自定義網絡
ycy@ubuntu18:~$ docker network create -d bridge --subnet 172.20.0.0/24 --gateway 172.20.0.1 br0
f8eb445161aa2291a1f89ee7879c2825e7c9a556b1f400f78181b62f8f9ff570
ycy@ubuntu18:~$ docker network create -d bridge --subnet 172.21.0.0/24 --gateway 172.21.0.1 br1
65c9dd48d5b57d70c845fd4ce1a287cd7d4c864a6b641560efb71049ffbf4a05
創建兩個測試容器,分別加入創建的網絡
ycy@ubuntu18:~$ docker run -it -d --name s0 --network br0 --ip 172.20.0.100 nginx /bin/bash
e28178cb59210b488efdf00519d135609664957fd2ee32cbd28a9119ea4f566b
ycy@ubuntu18:~$ docker run -it -d --name s1 --network br1 --ip 172.21.0.100 nginx /bin/bash
1afbf57debaa8a7150243cabcebaf9628d10c328cec1c8992379f01713f80d91
將當前容器加入到需要與之通信的網絡
ycy@ubuntu18:~$ docker network connect br1 s0
ycy@ubuntu18:~$ docker container attach s0
測試網絡連接
root@e28178cb5921:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.20.0.100 netmask 255.255.255.0 broadcast 172.20.0.255
ether 02:42:ac:14:00:64 txqueuelen 0 (Ethernet)
RX packets 26 bytes 3106 (3.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.21.0.2 netmask 255.255.255.0 broadcast 172.21.0.255
ether 02:42:ac:15:00:02 txqueuelen 0 (Ethernet)
RX packets 19 bytes 2462 (2.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
2.2 跨主機容器間的通信
2.2.1 macvlan
- macvlan網絡容器接口直接與主機網卡連接,無需NAT或端口映射。
- macvlan會獨佔主機網卡,但可以使用vlan子接口實現多macvlan網絡。
- macvlan網絡在二層上是隔離的,所以不同macvlan網絡的容器是不能通信的。
- 可以在三層上通過網關將macvlan網絡聯通起來。
- docker本身不做任何限制,像傳統vlan網絡那樣管理即可。
網卡開啓混雜模式
[root@CentOS7 ~]# ip link set ens37 promisc on
創建macvlan網絡
使用-d macvlan創建macvlan網絡,使用-o parent指定流量在docker主機上實際通過的物理接口
[root@CentOS7 ~]# docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=ens37 macvlan1
8a36aca364caeff25642c843fc0d3064bd74a60985545954b59e0b8bc3218d3f
開啓一個橋接macvlan的容器
[root@CentOS7 ~]# docker run -it --name s0 --network macvlan1 --ip 172.20.0.100 docker.io/centos
[root@e5519dccc6f2 /]#
另一個虛擬機也做類似配置
ycy@ubuntu18:~$ sudo ip link set ens38 promisc on
ycy@ubuntu18:~$ docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=ens38 macvlan1
9042e03b3242184498fc6ca2afae7953f776ec299ba8d05f21b1bbf240b32e71
ycy@ubuntu18:~$ docker run -it --name s1 --network macvlan1 --ip 172.20.0.200 nginx
root@8f8c30548017:/#
測試網絡連通性