本文介绍 Docker
包括5中常见的网路模式,并介绍容器间通信的常用方法。
Docker 的网络模式
docker run 可以通过 --net
选项执行容器的网络模式,Docker 支持5种
网络模式:
- Bridge 模式:
--net=bridge
默认设置。容器使用独立的 network namespace,并连接的 docker0 虚拟网桥,通过 iptables nat 表配置和宿主机的通信。容器和虚拟网桥通过 veth pair 连接,参考:使用 Linux bridge/netns 连接 Docker 容器
- Host 模式:
--net=host
,和宿主机共用一个 network namespace
- Container 模式:
--net=<container_id or container_name>
,和宿主机上另外一个容器共用同一个 network namespace
- None 模式:
--net=none
,关闭网络功能
- 自定义网络
Bridge 模式
docker
启动时会创建名称为 docker0
的虚拟网桥
,172.17.0.0/16
网段作为容器的ip地址,在主机上创建一对虚拟网卡veth pair
设备,Docker
将 veth pair
设备的一端放在新创建的容器中,并命名为eth0
(容器的网卡),另一端放在主机中,以vethxxx
这样类似的名字命名,并将这个网络设备加入到 docker0
网桥中。设备信息如下:
[root@xiexianbin_cn ~]# brctl show
bridge name bridge id STP enabled interfaces
bridge0 8000.56f4ae5194a7 no vethb573bb7
vethff5318a
docker0 8000.02421b3c34c5 no
[root@xiexianbin_cn ~]# ip a s vethff5318a # ifconfig vethff5318a
vethff5318a: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::c85c:ddff:fe34:6cb prefixlen 64 scopeid 0x20<link>
ether ca:5c:dd:34:06:cb txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 656 (656.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
示例:
docker run -it -d --privileged --name c7-1 xiexianbin/centos:7-net /sbin/init
docker run -it -d --privileged --name c7-2 xiexianbin/centos:7-net /sbin/init
brctl show
docker exec -it c7-1 /bin/bash
hostname -I
网络结构

端口转发参考:Docker 端口映射原理
指定网桥配置
接下来介绍通过新建网桥
来指定docker
容器的IP地址段的方法。
yum install -y bridge-utils
详见:
brctl addbr bridge0
ip addr add 192.168.1.0/24 dev bridge0
ip link set dev bridge0 up # 或 ifconfig bridge0 up
然后使用ifconfig
即可以看到新建的网桥bridge0
编辑/etc/dcoker/daemon.json
:
{
"bridge": "bridge0"
}
重启systemctl restart docker
生效,然后在创建的容器,默认使用192.168.1.0/24
的网段地址。
也可以通过如下命令看到:
[root@xiexianbin_cn ~]# docker network inspect bridge -f '{{json .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":"bridge0","com.docker.network.driver.mtu":"1500"}
[root@xiexianbin_cn ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://i71btyn2.mirror.aliyuncs.com"],
"bridge": "bridge0"
}
[root@xiexianbin_cn ~]# brctl show
bridge name bridge id STP enabled interfaces
bridge0 8000.000000000000 no
docker0 8000.02421b3c34c5 no
[root@xiexianbin_cn ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
d63831be7f2f bridge bridge local
669676e4bef2 host host local
0e5ef270567c none null local
[root@xiexianbin_cn ~]# docker network inspect d63831be7f2f
[
{
"Name": "bridge",
"Id": "d63831be7f2feccb31a523fb6908f42e387db075a441129e01b7eae150de3138",
"Created": "2021-03-13T08:05:49.026567116-04:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "192.168.1.0/24"
}
]
},
...
PS:
- 也可以通过配置启动参数(
systemctl cat docker.service
找到启动文件,修改 ExecStart=/usr/bin/dockerd --bip=CIDR
)指定网桥和网段
-b BRIDGE
or --bridge=BRIDGE
–指定容器挂载的网桥
–bip=CIDR
–定制 docker0 的掩码
端口转发
Docker 端口映射原理
Host 模式
启动容器的时候,指定 --net=host
,docker
将不会创建独立的 Network Namespace
,而是和宿主机共用一个Network Namespace
,包括IP地址和端口。但容器的文件系统、进程等和宿主机隔离。
示例:
docker run -it -d --privileged --net=host --name c7-1 xiexianbin/centos:7-net /sbin/init
ifconfig –a # 可以看到和宿主机相同的网络信息
Container 模式
--net=container:c7-1
新创建的容器和已经存在的一个容器共享一个 Network Namespace
,共享 IP、端口范围。但容器的文件系统、进程等和宿主机隔离。两个容器的进程可以通过 lo 网卡设备通信。
示例:
docker run -it -d --net=container:c7-1 --name c7-2 xiexianbin/centos:7-net /sbin/init
docker exec -it c7-1 ip a # 可以看到2个容器的IP地址相同
docker exec -it c7-2 ip a
None 模式
--net=none
Docker 容器会有自己的 Network Namespace
,但不进行任何网络配置,就是说该容器没有网卡、IP、路由等信息,需要使用者自行定制容器网络信息。
示例:
docker run -it -d --net=none --name c7 xiexianbin/centos:7-net /sbin/init
docker exec -it c7 ip a
docker inspect c7 # 看到如下的网络信息为空
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"none": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "0e5ef270567cd77fd0a594ea2abf5974fe29fe2a98c6d708466236b07982d723",
"EndpointID": "19a2c24c7596b61940cea8c183a900ba16c362bfe414b13d45ef56f9f8c9dd6b",
"Gateway": "",
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "",
"DriverOpts": null
}
}
该方式可以与 linux bridge
联合配置网路,demo示例参考:使用 Linux bridge/netns 连接 Docker 容器
自定义网络
docker 1.9
版本以后新增的特性,允许容器使用第三方的网络实现或者创建单独的bridge
网络,提供网络隔离能力。
容器间通信
Docker
容器间通信有3种方式:
- 通过容器IP通信
- 通过宿主机IP + 容器暴露的端口通信
- 通过
--link
通信(自动在 /etc/hosts
中添加容器的解析)(已标记废弃)
- 通过自定义network实现通信(
docker network create
),该方式与默认的docker0网络不同,可以通过 hostname ping 同一网络中的主机