8.1 Docker的默认的网络通信
8.1.1 Docker安装后默认的网络设置
Docker服务安装完成之后,默认在每个宿主机会生成一个名称为docker0的网卡,其ip地址都是172.17.0.1/16
root@ubuntu-2010:~# ip a
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:e0:e8:04:f5 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:e0ff:fee8:4f5/64 scope link
valid_lft forever preferred_lft forever
root@ubuntu-2010:~# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242e0e804f5 no
8.1.2 创建容器后的网络配置
每次新建容器后
- 宿主机多了一个虚拟网卡,和容器的网卡组合成一个网卡,比如: 137: veth8ca6d43@if136,而在容器内的网卡名为136,可以看出和宿主机的网卡之间的关联
- 容器会自动获取一个172.17.0.0/16网段的随机地址,默认从172.17.0.2开始,第二次容器为172.17.0.3,以此类推
- 容器获取的地址并不固定,每次容器重启,可能会发生地址变化
8.1.2.1 创建第一个容器后的网络状态
创建容器后,容器自动获取ip地址
root@ubuntu-2010:~# docker run -ti --rm alpine sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
80: eth0@if81: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
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
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 11a5e589ef8a
# root@ubuntu-2010:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
11a5e589ef8a alpine "sh" 30 seconds ago Up 29 seconds trusting_swartz
新建第一个容器,宿主机的网卡状态
root@ubuntu-2010:~# 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:ee:4a:fa brd ff:ff:ff:ff:ff:ff
altname enp2s1
altname ens33
inet 10.0.0.210/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feee:4afa/64 scope link
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:e0:e8:04:f5 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:e0ff:fee8:4f5/64 scope link
valid_lft forever preferred_lft forever
81: veth9e40094@if80: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether f6:bf:36:e7:d4:17 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::f4bf:36ff:fee7:d417/64 scope link
valid_lft forever preferred_lft forever
查看新建容器后桥接状态
root@ubuntu-2010:~# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242e0e804f5 no veth9e40094
8.1.2.1 创建第二个容器后的网络状态
再次创建第二个容器
root@ubuntu-2010:~# docker run -ti --rm alpine sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
82: eth0@if83: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
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
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 d40a93c0f6c3
/ # ping f92aa8306175
PING f92aa8306175 (69.172.200.109): 56 data bytes
^C
--- f92aa8306175 ping statistics ---
7 packets transmitted, 0 packets received, 100% packet loss
/ # ping d40a93c0f6c3
PING d40a93c0f6c3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.027 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.046 ms
64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.065 ms
root@ubuntu-2010:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d40a93c0f6c3 alpine "sh" 2 minutes ago Up 2 minutes exciting_kirch
11a5e589ef8a alpine "sh" 7 minutes ago Up 7 minutes trusting_swartz
新建第二个容器后又多了一个虚拟网卡
root@ubuntu-2010:~# 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:ee:4a:fa brd ff:ff:ff:ff:ff:ff
altname enp2s1
altname ens33
inet 10.0.0.210/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feee:4afa/64 scope link
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:e0:e8:04:f5 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:e0ff:fee8:4f5/64 scope link
valid_lft forever preferred_lft forever
81: veth9e40094@if80: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether f6:bf:36:e7:d4:17 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::f4bf:36ff:fee7:d417/64 scope link
valid_lft forever preferred_lft forever
83: veth7da37ea@if82: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 46:4a:fd:66:a5:ed brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::444a:fdff:fe66:a5ed/64 scope link
valid_lft forever preferred_lft forever
查看新建第二个容器后桥接状态
root@ubuntu-2010:~# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242e0e804f5 no veth7da37ea
veth9e40094
8.1.3 容器间通信
8.1.3.1 同一个宿主机的不同容器可互相通信
默认情况下
- 同一个宿主机的不同容器之间可以相互通信
dockerd --icc Enable inter-container communication (default true)
--icc=false 可以禁止通信
- 不同宿主机之间的容器IP地址重复,不能相互通信
同一宿主机的容器之间访问
root@ubuntu-2010:~# docker run -ti alpine sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
94: eth0@if95: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
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
# root@ubuntu-2010:~# docker run -ti --rm alpine sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
96: eth0@if97: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
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
/ # 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.156 ms
64 bytes from 172.17.0.1: seq=1 ttl=64 time=0.058 ms
^C
--- 172.17.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.058/0.107/0.156 ms
/ # 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.186 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.073 ms
^C
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.073/0.129/0.186 ms
8.1.3.2 禁止同一宿主机的不同容器间通信
范例:同一宿主机不同容器间禁止通信
#dockerd的--icc=false 选项可以禁止同一个宿主机的不同容器间通信
root@ubuntu-2010:~# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --icc=false
root@ubuntu-2010:~# systemctl daemon-reload
root@ubuntu-2010:~# systemctl restart docker
#--icc选项本质是修改iptables规则,pre.filter是--icc=true,pre2.filter是--icc=false
root@ubuntu-2010:~# iptables -S > pre2.filter
root@ubuntu-2010:~# diff pre.filter pre2.filter
13c13
< -A FORWARD -i docker0 -o docker0 -j ACCEPT
---
> -A FORWARD -i docker0 -o docker0 -j DROP
8.1.4 修改默认网络设置使用自定义网桥
新建容器默认使用docker0的网络配置,可以修改默认指向自定义的网桥网络
- 用自定义的网桥替代默认的docker0
root@ubuntu-2010:~# 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:89:46:ef brd ff:ff:ff:ff:ff:ff
altname enp2s1
altname ens33
inet 10.0.0.200/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe89:46ef/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:60:77:12:9d 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
root@ubuntu-2010:~# apt -y install bridge-utils
root@ubuntu-2010:~# brctl addbr br0
root@ubuntu-2010:~# ip a a 192.168.100.1/24 dev br0
root@ubuntu-2010:~# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.000000000000 no
docker0 8000.02426077129d no
root@ubuntu-2010:~# 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:89:46:ef brd ff:ff:ff:ff:ff:ff
altname enp2s1
altname ens33
inet 10.0.0.200/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe89:46ef/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:60:77:12:9d 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
4: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 1a:83:16:1d:43:89 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.1/24 scope global br0
valid_lft forever preferred_lft forever
root@ubuntu-2010:~# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
-b br0
root@ubuntu-2010:~# systemctl daemon-reload
root@ubuntu-2010:~# systemctl restart docker
root@ubuntu-2010:~# ps -ef | grep dockerd
root 97066 1 1 04:46 ? 00:00:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -b br0
root 97196 93416 0 04:46 pts/0 00:00:00 grep --color=auto dockerd
root@ubuntu-2010:~# docker run --rm alpine hostname -i
192.168.100.2
8.2 容器名称互联
新建容器时,docker会给容器自动分配名称,容器ID和IP地址,导致容器名称,容器ID和IP不固定,那么如何区分不同的容器,实现和确定目标容器通信呢?解决方案是给容器起个固定的名称,容器之间通过固定名称实现确定目标的通信
有两种固定名称:
- 容器名称
- 容器名称的别名
注意:两种方式都是最少需要两个容器才能实现
8.2.1 通过容器名称互联
8.2.1.1 容器名称介绍
在同一宿主机上的容器之间可以通过自定义的容器名称相互访问,比如:一个业务前端静态页面是使用nginx,动态页面使用的是tomcat,另外还需要负载均衡调度器,如:haproxy对请求调度至nginx和tomcat容器,由于容器在启动的时候其内部IP地址是DHCP随机分配的,而给容器起个固定的名称,则是相对比较固定的,因此比较适用于此场景
注意:如果被引用的容器地址变化,必须重启当前容器才能生效
8.2.1.2 容器名称实现
docker run 创建容器,可使用–link选项实现容器名称的引用,其本质就是在容器内的/etc/hosts中添加–link后指定的容器的IP和主机名的对应关系,从而实现名称解析
--link list Add link to another container
格式:
docker run --name <容器名称> #先创建指定名称的容器
docker run --link <目标通信的容器ID或容器名称> #再创建容器时引用上面容器的名称
8.2.1.3 案例:使用容器名称进行容器间通信
- 先创建第一个指定容器名称的容器
root@ubuntu-2010:~# docker run -ti --rm --name server1 alpine
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 de8bf4af716f
- 新建第二个容器时引用第一个容器的名称
会自动将第一个主机的名称加入/etc/hosts文件,从而可以利用第一个容器名称进行访问
root@ubuntu-2010:~# docker run -ti --rm --name server2 --link server1 alpine
/ # env
HOSTNAME=555be633aa00
SHLVL=1
HOME=/root
SERVER1_NAME=/server2/server1
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 server1 de8bf4af716f
172.17.0.3 555be633aa00
/ # ping server1
PING server1 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.131 ms
8.2.2 通过自定义容器别名互联
8.2.2.1 容器别名介绍
自定义的容器名称可能后期会发生变化,那么一旦名称发生变化,容器内程序之间也必须要随之发生变化,比如:程序通过固定的容器名称进行服务调用,但是容器名称发生变化后再使用之前的名称肯定是无法成功调用,每次都进行更改的话又比较麻烦,因此可以使用自定义别名的方式解决,即容器名称可以随意更改,只要不更改别名即可
8.2.2.2 容器别名实现
命令格式:
docker run --name <容器名称> #先创建指定名称的容器
docker run --name <容器名称> --link <目标容器名称>:"<容器别名1> <容器别名2> ..." #给上
面创建的容器起别名,来创建新容器
8.2.2.3 案例:使用容器别名
- 创建第三个容器,引用前面的容器,并起多个别名
root@ubuntu-2010:~# docker run -ti --rm --name server3 --link server1:"server1-alias1 server1-alias2" --link server2:server2-alias alpine
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 server1-alias1 server1-alias2 de8bf4af716f server1
172.17.0.3 server2-alias 555be633aa00 server2
172.17.0.4 899144bbda6c
8.3 docker网络连接
8.3.1 docker网络模式介绍
Docker的网络支持5种网络模式
- none
- bridge
- host
- container
- network-name
查看默认的网络模式有三个
root@ubuntu-2010:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
00b5433d68e7 bridge bridge local
784ef8827cf0 host host local
77884fabbcfa none null local
8.3.2 网络模式指定
默认新建的容器使用Bridge模式,创建容器时,docker run 命令使用以下选项指定网络模式
格式:
docker run --network <mode>
docker run --net=<mode>
<mode>: 可是以下值
none
bridge
host
container:<容器名或容器ID>
<自定义网络名称>
8.3.3 bridge网络模式
8.3.3.1 bridge 网络模式架构


此模式宿主机需要启动ip_forward功能
bridge网络模式特点
- 网络资源隔离: 不同宿主机的容器无法直接通信,各自使用独立网络
- 无需手动配置: 容器默认自动获取172.17.0.0/16的IP地址,此地址可以修改
- 可访问外网: 利用宿主机的物理网卡,SNAT连接外网
- 外部主机无法直接访问容器: 可以通过配置DNAT接受外网的访问
- 低性能较低: 因为可通过NAT,网络转换带来更的损耗
- 端口管理繁琐: 每个容器必须手动指定唯一的端口,容器产生端口冲突
8.3.3.2 bridge 模式的默认设置
- 查看bridge模式信息
root@ubuntu-2010:~# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "00b5433d68e7d322876e91c65f81402d0a68bbf7d1f9795da727c1c894400432",
"Created": "2021-09-21T04:48:57.827808699Z",
"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": {
"555be633aa009dca31bc9004f96a011479ba5f9a5b4b104c8a6ec6abcc9cc525": {
"Name": "server2",
"EndpointID": "40403adee3ac783358294829677b32cfff41ae548e6a43ca93c50c67583de604",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"899144bbda6cd47053a0315db72f1112238962db521a3820e0d1c1547ec00bf3": {
"Name": "server3",
"EndpointID": "d472f228d0a1b5bac65697407b3126f6c84f015881c02765eef6bf9cc2365355",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/16",
"IPv6Address": ""
},
"de8bf4af716fa4c64fb9a7c3a4a962accc23f3dd62be73e4e510a8205663e254": {
"Name": "server1",
"EndpointID": "6dbdb2af8fe2c5c00666b846a1d42767af52c7272d136bc06e933227b193fa61",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"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": {}
}
]
- 宿主机的网络状态
root@ubuntu-2010:~# cat /proc/sys/net/ipv4/ip_forward
1
root@ubuntu-2010:~# iptables -S -t nat
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P POSTROUTING ACCEPT
-P OUTPUT ACCEPT
-N DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A DOCKER -i docker0 -j RETURN
root@ubuntu-2010:~# iptables -vnL -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER all -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
- 通过宿主机的物理网卡利用SNAT访问外部网络
#在另一台主机上建立httpd服务器
[root@centos7 ~]# echo `hostname -I` > /var/www/html/index.html
[root@centos7 ~]# curl localhost
10.0.0.7
[root@centos7 ~]# systemctl is-active httpd
active
#启动容器,默认是bridge网络模式
root@ubuntu-2010:~# docker run -ti --rm alpine sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
106: eth0@if107: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
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
/ # ping 10.0.0.7
PING 10.0.0.7 (10.0.0.7): 56 data bytes
64 bytes from 10.0.0.7: seq=0 ttl=63 time=1.006 ms
64 bytes from 10.0.0.7: seq=1 ttl=63 time=0.829 ms
^C
--- 10.0.0.7 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.829/0.917/1.006 ms
/ # ping -c 1 www.baidu.com
PING www.baidu.com (14.215.177.39): 56 data bytes
64 bytes from 14.215.177.39: seq=0 ttl=127 time=7.417 ms
--- www.baidu.com ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 7.417/7.417/7.417 ms
/ # wget -qO - 10.0.0.7
10.0.0.7
[root@centos7 ~]# tail /var/log/httpd/access_log
10.0.0.210 - - [21/Sep/2021:21:59:40 +0800] "GET / HTTP/1.1" 200 9 "-" "Wget"
8.3.3.3 修改默认的bridge模式网络配置
有两种方法修改默认的bridge模式的网络配置,但两种方式只能选一种,否则会导致冲突,docker服务无法启动
- 修改/lib/systemd/system/docker.service,此方法以在之前做过介绍
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
--bip=10.100.0.1/24
- 修改/etc/docker/daemon.json
root@ubuntu-2010:~# vim /etc/docker/daemon.json
{
"registry-mirrors":["https://hub-mirror.c.163.com"],
"bip": "172.30.0.1/24"
}
root@ubuntu-2010:~# systemctl daemon-reload
root@ubuntu-2010:~# systemctl restart docker
root@ubuntu-2010:~# 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:89:46:ef brd ff:ff:ff:ff:ff:ff
altname enp2s1
altname ens33
inet 10.0.0.200/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe89:46ef/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:60:77:12:9d brd ff:ff:ff:ff:ff:ff
inet 172.30.0.1/24 brd 172.30.0.255 scope global docker0
valid_lft forever preferred_lft forever
root@ubuntu-2010:~# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "a81034a5226ad868e70a5a05cc80f57f141f8518af78a11bba63a450ca88b8d3",
"Created": "2021-09-21T14:05:32.805271015Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.30.0.0/24",
"Gateway": "172.30.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": {}
}
]
8.3.4 Host模式

此模式由于直接使用宿主机的网络无需转换,网络性能最高,但是各容器内使用的端口不能相同,适用于运行容器端口比较固定的业务
Host网络模式特点:
- 使用参数 –network host 指定
- 共享宿主机网络
- 网络性能无损耗
- 网络故障排除相对简单
- 各容器网络无隔离
- 网络资源无法分别统计
- 端口管理困难:容易产生端口冲突
- 不支持端口映射
#确认宿主机网络设置
root@ubuntu-2010:~# 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:e0ff:fee8:4f5 prefixlen 64 scopeid 0x20<link>
ether 02:42:e0:e8:04:f5 txqueuelen 0 (Ethernet)
RX packets 674 bytes 40278 (40.2 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 774 bytes 4319229 (4.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.210 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::20c:29ff:feee:4afa prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:ee:4a:fa txqueuelen 1000 (Ethernet)
RX packets 426075 bytes 338021839 (338.0 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 45795 bytes 3950660 (3.9 MB)
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 800 bytes 72950 (72.9 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 800 bytes 72950 (72.9 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@ubuntu-2010:~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.1 0.0.0.0 UG 0 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
#启动容器前确认是否有启用80端口
root@ubuntu-2010:~# lsof -i:80
#创建host模式的容器
root@ubuntu-2010:~# docker run -d --network host --name web1 httpd
24c8b8645449e70ccbad8a5f040e2a76a14809ee6edda117ea7d15c3a0f00498
#创建容器后,宿主机的80/tcp端口打开
root@ubuntu-2010:~# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 89788 root 4u IPv6 398309 0t0 TCP *:http (LISTEN)
httpd 89807 daemon 4u IPv6 398309 0t0 TCP *:http (LISTEN)
httpd 89808 daemon 4u IPv6 398309 0t0 TCP *:http (LISTEN)
httpd 89809 daemon 4u IPv6 398309 0t0 TCP *:http (LISTEN)
#进入容器
root@ubuntu-2010:~# docker exec -ti web1 bash
root@ubuntu-2010:/# apt update
root@ubuntu-2010:/# apt -y install net-tools
root@ubuntu-2010:/# 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:e0ff:fee8:4f5 prefixlen 64 scopeid 0x20<link>
ether 02:42:e0:e8:04:f5 txqueuelen 0 (Ethernet)
RX packets 674 bytes 40278 (39.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 774 bytes 4319229 (4.1 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.210 netmask 255.255.255.0 broadcast 10.0.0.255
inet6 fe80::20c:29ff:feee:4afa prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:ee:4a:fa txqueuelen 1000 (Ethernet)
RX packets 454240 bytes 375942865 (358.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 49764 bytes 4294600 (4.0 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 872 bytes 79454 (77.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 872 bytes 79454 (77.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@ubuntu-2010:/# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.1 0.0.0.0 UG 0 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
root@ubuntu-2010:/# echo "Test Page in app" > usr/share/nginx/html/index.html
#从容器访问远程主机
root@ubuntu-2010:/# curl 10.0.0.7
10.0.0.7
#查看远程主机的访问日志
[root@centos7 ~]# tail /var/log/httpd/access_log
10.0.0.210 - - [21/Sep/2021:22:24:51 +0800] "GET / HTTP/1.1" 200 9 "-" "curl/7.64.0"
#远程主机可以访问容器的web服务
[root@centos7 ~]# curl 10.0.0.210
Test Page in app
8.3.5 none 模式
在使用none模式后,Docker容器不会进行任何网络配置,没有网卡、没有IP,也没有路由,因此默认无法与外界通信,需要手动添加网卡配置IP等,所以极少使用
none 模式特点:
- 使用参数 –network none 指定
- 默认无网络功能,无法和外部通信
启动一个none模式的容器
root@ubuntu-2010:~# docker run -ti --network none -p 80:80 --name web1-none alpine
/ #
/ # ifconfig -a
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
/ # ping -c 1 baidu.com
ping: bad address 'baidu.com'
/ # ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1): 56 data bytes
ping: sendto: Network unreachable
8.3.6 Container 模式

Container模式特点:
- 使用参数 –-network container:名称或ID 指定
- 与宿主机网络空间隔离
- 空器间共享网络空间
- 适合频繁的容器间的网络通信
- 直接使用对方的网络,较少使用
root@ubuntu-2010:~# docker run -ti --name server1 -p 80:80 alpine sh
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:736 (736.0 B) TX bytes:0 (0.0 B)
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)
/ # netstat -ntl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
root@ubuntu-2010:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d87febb07525 alpine "sh" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp server1
root@ubuntu-2010:~# docker port server1
80/tcp -> 0.0.0.0:80
80/tcp -> :::80
root@ubuntu-2010:~# curl localhost
curl: (56) Recv failure: Connection reset by peer
#创建第二个容器,基于第一个容器的container的网络模式
root@ubuntu-2010:~# docker run -d --name server2 --network container:server1 nginx
#可以访问web服务
root@ubuntu-2010:~# curl localhost
Welcome to nginx!
root@d87febb07525:/# 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 1568 bytes 9748112 (9.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1419 bytes 85349 (83.3 KiB)
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@d87febb07525:/# netstat -ntl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp6 0 0 :::80 :::* LISTEN
#可以访问外网
root@d87febb07525:/# curl -I baidu.com
HTTP/1.1 200 OK
Date: Tue, 21 Sep 2021 14:59:07 GMT
Server: Apache
Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT
ETag: "51-47cf7e6ee8400"
Accept-Ranges: bytes
Content-Length: 81
Cache-Control: max-age=86400
Expires: Wed, 22 Sep 2021 14:59:07 GMT
Connection: Keep-Alive
Content-Type: text/html
8.3.7 自定义网络模式
除了以上的网络模式,也可以自定义网络,使用自定义的网段地址,网关等信息
注意:自定义网络可以直接通过容器名进行相互的访问,而无需使用–link
可以使用自定义网络模式,实现不同集群应用的独立网络管理,而互不影响,而且在同一个网络内,可以直接利用容器名相互访问,非常便利
8.3.7.1 自定义网络实现
[root@ubuntu1804 ~]#docker network --help
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
创建自定义网络:
docker network create -d <mode> --subnet <CIDR> --gateway <网关> <自定义网络名称>
#注意mode不支持host和none,默认是bridge模式
查看自定义网络信息
docker network inspect <自定义网络名称或网络ID>
引用自定义网络
docker run --network <自定义网络名称> <镜像名称>
删除自定义网络
doccker network rm <自定义网络名称或网络ID>
内置的三个网络无法删除
root@ubuntu-2010:~# docker network rm none
Error response from daemon: none is a pre-defined network and cannot be removed
root@ubuntu-2010:~# docker network rm host
Error response from daemon: host is a pre-defined network and cannot be removed
root@ubuntu-2010:~# docker network rm bridge
Error response from daemon: bridge is a pre-defined network and cannot be removed
8.3.7.2 自定义网络案例
root@ubuntu-2010:~# docker network create -d bridge --subnet 172.27.0.0/24 --gateway 172.27.0.1 test-net
58c792ac9e6cc680e3d60bb45e84149aa21f8f5c4cc315be44c8b2bb5aad9a6f
root@ubuntu-2010:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
00b5433d68e7 bridge bridge local
784ef8827cf0 host host local
77884fabbcfa none null local
58c792ac9e6c test-net bridge local
root@ubuntu-2010:~# docker inspect test-net
[
{
"Name": "test-net",
"Id": "58c792ac9e6cc680e3d60bb45e84149aa21f8f5c4cc315be44c8b2bb5aad9a6f",
"Created": "2021-09-21T15:06:19.430890453Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.27.0.0/24",
"Gateway": "172.27.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
root@ubuntu-2010:~# 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:ee:4a:fa brd ff:ff:ff:ff:ff:ff
altname enp2s1
altname ens33
inet 10.0.0.210/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feee:4afa/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:e0:e8:04:f5 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:e0ff:fee8:4f5/64 scope link
valid_lft forever preferred_lft forever
#添加了一个虚拟网卡
110: br-58c792ac9e6c: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:8b:f7:8e:09 brd ff:ff:ff:ff:ff:ff
inet 172.27.0.1/24 brd 172.27.0.255 scope global br-58c792ac9e6c
valid_lft forever preferred_lft forever
#新增一个网桥
root@ubuntu-2010:~# brctl show
bridge name bridge id STP enabled interfaces
br-58c792ac9e6c 8000.02428bf78e09 no
docker0 8000.0242e0e804f5 no
root@ubuntu-2010:~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.1 0.0.0.0 UG 0 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.27.0.0 0.0.0.0 255.255.255.0 U 0 0 0 br-58c792ac9e6c
root@ubuntu-2010:~# docker run -ti --rm --network test-net alpine sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
111: eth0@if112: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:1b:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.27.0.2/24 brd 172.27.0.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.27.0.1 0.0.0.0 UG 0 0 0 eth0
172.27.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
/ # cat /etc/resolv.conf
search test.com test.org
nameserver 127.0.0.11
options edns0 trust-ad ndots:0
/ # ping -c1 baidu.com
PING baidu.com (220.181.38.251): 56 data bytes
64 bytes from 220.181.38.251: seq=0 ttl=127 time=42.409 ms
--- baidu.com ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 42.409/42.409/42.409 ms
#再次检查网络信息,会出现此网络中容器的网络信息
root@ubuntu-2010:~# docker network inspect test-net
[
{
"Name": "test-net",
"Id": "58c792ac9e6cc680e3d60bb45e84149aa21f8f5c4cc315be44c8b2bb5aad9a6f",
"Created": "2021-09-21T15:06:19.430890453Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.27.0.0/24",
"Gateway": "172.27.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"b2cfd15944c41c90c0d730d5bc6f58525514da7996243485d63fe011b3492f11": {
"Name": "keen_napier",
"EndpointID": "62c6a487c8efbd287538ef3c4e866564b6b39f0bf08382045fbbe1b7c1e6b48a",
"MacAddress": "02:42:ac:1b:00:02",
"IPv4Address": "172.27.0.2/24",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
8.3.7.3 自定义网络中的容器之间通信案例
root@ubuntu-2010:~# docker run -ti --rm --network test-net --name test1 alpine sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
113: eth0@if114: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:1b:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.27.0.2/24 brd 172.27.0.255 scope global eth0
valid_lft forever preferred_lft forever
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.27.0.2 5233b632f2c5
root@ubuntu-2010:~# docker run -ti --rm --network test-net --name test2 alpine sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
115: eth0@if116: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:1b:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.27.0.3/24 brd 172.27.0.255 scope global eth0
valid_lft forever preferred_lft forever
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.27.0.3 60cd2e5d9c1e
/ # ping -c1 test1
PING test1 (172.27.0.2): 56 data bytes
64 bytes from 172.27.0.2: seq=0 ttl=64 time=0.160 ms
--- test1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.160/0.160/0.160 ms
结论:自定义网络中的容器之间可以直接利用容器名进行通信
8.3.8 同一个宿主机之间不同网络的容器通信
开两个容器,一个使用自定义网络容器,一个使用默认bridge网络的容器,默认无法通信,利用单臂路由实现通信

root@ubuntu-2010:~# docker run -ti --rm --name test1 alpine sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
117: eth0@if118: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
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
root@ubuntu-2010:~# docker run -ti --rm --network test-net --name test2 alpine sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
119: eth0@if120: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:1b:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.27.0.2/24 brd 172.27.0.255 scope global eth0
valid_lft forever preferred_lft forever
/ # ping -c1 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
--- 172.17.0.2 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
8.3.8.1 自定义网络和bridge网络容器之间无法通信的原因
root@ubuntu-2010:~# cat /proc/sys/net/ipv4/ip_forward
1
root@ubuntu-2010:~# brctl show
bridge name bridge id STP enabled interfaces
br-58c792ac9e6c 8000.02428bf78e09 no
docker0 8000.0242e0e804f5 no
root@ubuntu-2010:~# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
13 1069 DOCKER-USER all -- * * 0.0.0.0/0 0.0.0.0/0
13 1069 DOCKER-ISOLATION-STAGE-1 all -- * * 0.0.0.0/0 0.0.0.0/0
6 605 ACCEPT all -- * br-58c792ac9e6c 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
1 84 DOCKER all -- * br-58c792ac9e6c 0.0.0.0/0 0.0.0.0/0
5 296 ACCEPT all -- br-58c792ac9e6c !br-58c792ac9e6c 0.0.0.0/0 0.0.0.0/0
1 84 ACCEPT all -- br-58c792ac9e6c br-58c792ac9e6c 0.0.0.0/0 0.0.0.0/0
3447 27M ACCEPT all -- * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
1 84 DOCKER all -- * docker0 0.0.0.0/0 0.0.0.0/0
2853 132K ACCEPT all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0
1 84 ACCEPT all -- docker0 docker0 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
pkts bytes target prot opt in out source destination
6 380 DOCKER-ISOLATION-STAGE-2 all -- br-58c792ac9e6c !br-58c792ac9e6c 0.0.0.0/0 0.0.0.0/0
2853 132K DOCKER-ISOLATION-STAGE-2 all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0
6313 27M RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Chain DOCKER-USER (1 references)
pkts bytes target prot opt in out source destination
7350 32M RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Chain DOCKER-ISOLATION-STAGE-2 (2 references)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * br-58c792ac9e6c 0.0.0.0/0 0.0.0.0/0
1 84 DROP all -- * docker0 0.0.0.0/0 0.0.0.0/0
2858 132K RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
root@ubuntu-2010:~# iptables -I DOCKER-ISOLATION-STAGE-2 -j ACCEPT
root@ubuntu-2010:~# docker exec -ti test1 sh
/ # ping 172.27.0.2
PING 172.27.0.2 (172.27.0.2): 56 data bytes
64 bytes from 172.27.0.2: seq=0 ttl=63 time=0.116 ms
root@ubuntu-2010:~# docker exec -ti test2 sh
/ # ping -c1 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=63 time=0.089 ms
8.3.8.2 解决同一宿主机不同网络的容器间无法通信的问题
可以使用docker network connect命令实现同一个宿主机不同网络的容器间相互通信
#将CONTAINER连入指定的NETWORK中,使此CONTAINER可以与CONTAINER中的其它容器进行通信
docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias strings Add network-scoped alias for the container
--driver-opt strings driver options for the network
--ip string IPv4 address (e.g., 172.30.100.104)
--ip6 string IPv6 address (e.g., 2001:db8::33)
--link list Add link to another container
--link-local-ip strings Add a link-local address for the container
#将CONTAINER与指定的NETWORK断开连接,使此CONTAINER可以与CONTAINER中的其它容器进行无法通信
#如果将容器从自定义的网络删除,将加入默认的网络,即docker0网桥中,获取172.17.0.0/16
#如果将容器从默认的网络docker0删除,将加入none网络
docker network disconnect [OPTIONS] NETWORK CONTAINER
Disconnect a container from a network
Options:
-f, --force Force the container to disconnect from a network
- test1和test2的容器默认无法通信
#每个网络中有属于此网络的容器信息
root@ubuntu-2010:~# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "0de69e06e3516476a8b6b83fe6a29ef97acb0d741a8d577a6d622fe19a9ce954",
"Created": "2021-09-21T15:36:19.025464664Z",
"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": {
"5c1a35deafba77fc0811cee5135562f80eb09e76176468f4d5f112edb294ef5d": {
"Name": "test1",
"EndpointID": "bf3ee6efb34fc96491e5473ed143b7de3f9c1ad3ae5c9afb5eab2edfac49079f",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"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": {}
}
]
root@ubuntu-2010:~# docker network inspect test-net
[
{
"Name": "test-net",
"Id": "58c792ac9e6cc680e3d60bb45e84149aa21f8f5c4cc315be44c8b2bb5aad9a6f",
"Created": "2021-09-21T15:06:19.430890453Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.27.0.0/24",
"Gateway": "172.27.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"ec982db2a60b742c9859084a7809b290df472102db00879f5ae0124b6421ac4a": {
"Name": "test2",
"EndpointID": "4e7d2eb2633ade85bfd693f0b418a3a3ccdffdf6ca11c5576926008905f3d06f",
"MacAddress": "02:42:ac:1b:00:02",
"IPv4Address": "172.27.0.2/24",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
- 让默认网络中容器test1可以连通自定义网络的容器test2
root@ubuntu-2010:~# docker network connect test-net test1
root@ubuntu-2010:~# docker network inspect test-net
[
{
"Name": "test-net",
"Id": "58c792ac9e6cc680e3d60bb45e84149aa21f8f5c4cc315be44c8b2bb5aad9a6f",
"Created": "2021-09-21T15:06:19.430890453Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.27.0.0/24",
"Gateway": "172.27.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"5c1a35deafba77fc0811cee5135562f80eb09e76176468f4d5f112edb294ef5d": {
"Name": "test1",
"EndpointID": "c42bf659c8beacb4ff85da50aaa4a9bdfac4f573343affb6f3d165dcdb2fe2c6",
"MacAddress": "02:42:ac:1b:00:03",
"IPv4Address": "172.27.0.3/24",
"IPv6Address": ""
},
"ec982db2a60b742c9859084a7809b290df472102db00879f5ae0124b6421ac4a": {
"Name": "test2",
"EndpointID": "4e7d2eb2633ade85bfd693f0b418a3a3ccdffdf6ca11c5576926008905f3d06f",
"MacAddress": "02:42:ac:1b:00:02",
"IPv4Address": "172.27.0.2/24",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
#在test1容器中可以看到新添加了一个网卡,并且分配了test-net网络的IP信息
root@ubuntu-2010:~# docker exec -ti test1 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
5: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
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
9: eth1@if10: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:1b:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.27.0.3/24 brd 172.27.0.255 scope global eth1
valid_lft forever preferred_lft forever
/ # ping -c1 172.27.0.2
PING 172.27.0.2 (172.27.0.2): 56 data bytes
64 bytes from 172.27.0.2: seq=0 ttl=64 time=0.104 ms
--- 172.27.0.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.104/0.104/0.104 ms
#在test2容器中没有变化,仍然无法连接test1
root@ubuntu-2010:~# docker exec -ti test2 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
7: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:1b:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.27.0.2/24 brd 172.27.0.255 scope global eth0
valid_lft forever preferred_lft forever
/ # ping -c1 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
--- 172.17.0.2 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
- 让自定义网络中容器test2可以连通默认网络的容器test1
#将自定义网络中的容器test2也加入到默认网络中,使之和默认网络中的容器test1通信
root@ubuntu-2010:~# docker network connect bridge test2
root@ubuntu-2010:~# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "0de69e06e3516476a8b6b83fe6a29ef97acb0d741a8d577a6d622fe19a9ce954",
"Created": "2021-09-21T15:36:19.025464664Z",
"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": {
"5c1a35deafba77fc0811cee5135562f80eb09e76176468f4d5f112edb294ef5d": {
"Name": "test1",
"EndpointID": "bf3ee6efb34fc96491e5473ed143b7de3f9c1ad3ae5c9afb5eab2edfac49079f",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"ec982db2a60b742c9859084a7809b290df472102db00879f5ae0124b6421ac4a": {
"Name": "test2",
"EndpointID": "3f86e8375c6c23f220b9982a813a7747251db6b77b2ac05cb9f0b34890b63077",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
}
},
"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": {}
}
]
#确认自定义网络的容器test2中添加了新网卡,并设置默认网络的IP信息
root@ubuntu-2010:~# docker exec -ti test2 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
7: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:1b:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.27.0.2/24 brd 172.27.0.255 scope global eth0
valid_lft forever preferred_lft forever
11: eth1@if12: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
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 eth1
valid_lft forever preferred_lft forever
/ # ping -c1 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.099 ms
--- 172.17.0.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.099/0.099/0.099 ms
#在test2中可以利用test1容器名通信
/ # ping -c1 test1
PING test1 (172.27.0.3): 56 data bytes
64 bytes from 172.27.0.3: seq=0 ttl=64 time=0.071 ms
--- test1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.071/0.071/0.071 ms
#在test1中可以利用test2容器名通信
/ # ping -c1 test2
PING test2 (172.27.0.2): 56 data bytes
64 bytes from 172.27.0.2: seq=0 ttl=64 time=0.048 ms
--- test2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.048/0.048/0.048 ms
- 断开不同网络中的网络通信
#将test1 断开和网络test-net中其它容器的通信
root@ubuntu-2010:~# docker network disconnect test-net test1
root@ubuntu-2010:~# docker exec -ti test1 sh
/ # ping 172.27.0.2
PING 172.27.0.2 (172.27.0.2): 56 data bytes
8.4 实现跨宿主机的容器之间网络互联
同一个宿主机之间的各容器之间是可以直接通信的,但是如果访问到另一台宿主机的容器呢?
8.4.1 docker跨主机互联实现说明
跨主机互联是说A宿主机的容器可以访问B主机上的容器,但是前提是保证各宿主机之间的网络是可以相互通信的,然后各容器才可以通过宿主机访问到对方的容器
实现原理:是在宿主机做一个网络路由就可以实现A宿主机的容器访问B主机的容器的目的
注意:此方式只适合小型网络环境,复杂的网络或者大型的网络可以使用google开源的k8s进行互联
8.4.2 修改各宿主机网段
Docker默认网段是172.17.0.x/16,而且每个宿主机都是一样的,因此要做路由的前提是各个主机的网络不能一致
8.4.2.1 第一个宿主机A上更改网段
root@ubuntu-2010:~# cat /etc/docker/daemon.json
{
"registry-mirrors":["https://hub-mirror.c.163.com"],
"bip": "192.168.100.1/24"
}
root@ubuntu-2010:~# systemctl daemon-reload
root@ubuntu-2010:~# systemctl restart docker
root@ubuntu-2010:~# 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:6e:d1:fa brd ff:ff:ff:ff:ff:ff
altname enp2s1
altname ens33
inet 10.0.0.200/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe6e:d1fa/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:4a:91:5c:b6 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.1/24 brd 192.168.100.255 scope global docker0
valid_lft forever preferred_lft forever
root@ubuntu-2010:~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.1 0.0.0.0 UG 0 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.100.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0
8.4.2.2 第二个宿主机B更改网段
[root@centos8-1 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://3mihk855.mirror.aliyuncs.com"],
"bip": "192.168.200.1/24"
}
[root@centos8-1 ~]# systemctl daemon-reload
[root@centos8-1 ~]# systemctl restart docker
[root@centos8-1 ~]# 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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:3a:74:14 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.8/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::a380:5e8b:aac8:5a0c/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:2f:d5:74:88 brd ff:ff:ff:ff:ff:ff
inet 192.168.200.1/24 brd 192.168.100.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:2fff:fed5:7488/64 scope link
valid_lft forever preferred_lft forever
[root@centos8-1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.1 0.0.0.0 UG 100 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
192.168.200.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0
8.4.3 在两个宿主机分别启动一个容器
第一个宿主机启动容器server1
root@ubuntu-2010:~# docker run -ti --rm --name server1 alpine sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
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
第二个宿主机启动容器server2
[root@centos8-1 ~]# docker run -ti --rm --name server2 alpine sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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 state UP
link/ether 02:42:c0:a8:64:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.200.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.200.1 0.0.0.0 UG 0 0 0 eth0
192.168.200.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
从第一个宿主机的容器server1无法与第二个宿主机的server2互相访问
/ # ping -c1 192.168.100.2
PING 192.168.100.2 (192.168.100.2): 56 data bytes
--- 192.168.100.2 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
/ # ping -c1 192.168.200.2
PING 192.168.200.2 (192.168.200.2): 56 data bytes
--- 192.168.200.2 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
8.4.4 添加静态路由和iptables规则
在各宿主机添加静态路由,网关指向对方宿主机IP
8.4.4.1 在第一台宿主机添加静态路由和iptables规则
#添加路由
root@ubuntu-2010:~# route add -net 192.168.200.0/24 gw 10.0.0.8
#修改FORWARD默认规则
root@ubuntu-2010:~# iptables -P FORWARD ACCEPT
#或者修改iptables规则
root@ubuntu-2010:~# iptables -A FORWARD -s 10.0.0.0/24 -j ACCEPT
8.4.4.2 在第二台宿主机添加静态路由和iptables规则
#添加路由
[root@centos8-1 ~]# route add -net 192.168.100.0/24 gw 10.0.0.200
#修改FORWARD默认规则
[root@centos8-1 ~]# iptables -P FORWARD ACCEPT
#或者修改iptables规则
[root@centos8-1 ~]# iptables -A FORWARD -s 10.0.0.0/24 -j ACCEPT
8.4.5 测试跨宿主机之间容器互联
宿主机A的容器server1访问宿主机B容器server2,同时在宿主机B上tcpdump抓包观察
/ # ping -c1 192.168.200.2
PING 192.168.200.2 (192.168.200.2): 56 data bytes
64 bytes from 192.168.200.2: seq=0 ttl=62 time=0.987 ms
--- 192.168.200.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.987/0.987/0.987 ms
[root@centos8-1 ~]# tcpdump -i eth0 -nn icmp
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
16:18:01.118004 IP 10.0.0.200 > 192.168.200.2: ICMP echo request, id 8, seq 0, length 64
16:18:01.118139 IP 192.168.200.2 > 10.0.0.200: ICMP echo reply, id 8, seq 0, length 64
宿主机B的容器server2访问宿主机A的容器server1,同时在宿主机A上tcpdump抓包观察
/ # ping -c1 192.168.100.2
PING 192.168.100.2 (192.168.100.2): 56 data bytes
64 bytes from 192.168.100.2: seq=0 ttl=62 time=1.192 ms
--- 192.168.100.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.192/1.192/1.192 ms
root@ubuntu-2010:~# tcpdump -i eth0 -nn icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
08:19:17.244883 IP 10.0.0.8 > 192.168.100.2: ICMP echo request, id 8, seq 0, length 64
08:19:17.245031 IP 192.168.100.2 > 10.0.0.8: ICMP echo reply, id 8, seq 0, length 64
8.4.6 创建第三个容器测试
#在第二个宿主机B上启动第一个提供web服务的nginx容器server3
#注意无需打开端口映射
[root@centos8-1 ~]# docker run -d --name server3 nginx
[root@centos8-1 ~]# docker exec -ti server3 bash
root@e55a9e37da67:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.200.3 netmask 255.255.255.0 broadcast 192.168.200.255
ether 02:42:c0:a8:c8:03 txqueuelen 0 (Ethernet)
RX packets 4257 bytes 9328282 (8.8 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2599 bytes 143839 (140.4 KiB)
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
#从server1中访问server3的页面可以成功
/ # wget -qO - 192.168.200.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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>
#从server3容器观察访问日志,可以看到来自第一个宿主机,而非server1容器
[root@centos8-1 ~]# docker logs --tail 3 -f server3
2021/09/22 08:22:28 [alert] 1#1: unknown process 286 exited on signal 2
10.0.0.200 - - [22/Sep/2021:08:25:36 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"
10.0.0.200 - - [22/Sep/2021:08:27:21 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"