目录
介绍
当项目大规模使用 Docker 时,容器通信的问题也就产生了。要解决容器通信问题,必须先了解很多关于网络的知识。Docker一共有四种网络模式分别是host模式,container模式,none模式,bridge模式。
网络模式 | 参数 | 说明 |
host模式 | --net=host | 容器和宿主机共享 Network namespace |
container模式 | --net={id} | 容器和另外一个容器共享 Network namespace。 kubernetes 中的pod就是多个容器共享一个 Network namespace |
none模式 | --net=none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配 veth pair 和网桥连接,配置IP等 |
bridge模式 | --net=bridge | 默认为该模式,通过 -p 指定端口映射 |
Bridge模式
bridge模式是 docker 的默认网络模式,不写–net参数,就是bridge模式。使用docker run -p时,docker 实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。bridge模式如下图所示:
如果你之前有 Docker 使用经验,你可能已经习惯了使用--link参数来使容器互联。
随着 Docker 网络的完善,强烈建议大家将容器加入自定义的 Docker 网络来连接多个容器,而不是使用 --link 参数。
# 创建一个叫my-net的bridge类型的网络
[root@bogon ~]# docker network create -d bridge my-net
2171fab7109878ea43dadbd6b09f6395bd54ec691cb010ad7a4c2f0fcb7c4f46
# 查看都有哪些网络
[root@bogon ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
8cd27b16846c bridge bridge local
9095f54e4dee host host local
2171fab71098 my-net bridge local
be41d33662a5 none null local
# 运行一个容器并连接到新建的 my-net 网络
[root@bogon ~]# docker run -itd --rm --name busybox1 --network my-net busybox sh -c 'while true;do echo hello;done'
f7614d0e88f1eabf174d0cc4679e4f5407bf1c5fbb4c2932a5f8327ecaee4978
# 再运行一个容器并加入到 my-net 网络
[root@bogon ~]# docker run -it --rm --name busybox2 --network my-net busybox sh
/ # ping busybox1
PING busybox1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.059 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.059 ms
^C
--- busybox1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.059/0.059/0.059 ms
# 这样,busybox1 容器和 busybox2 容器建立了互联关系
# 如果你有多个容器之间需要互相连接,推荐使用Docker Compose
Host模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。 Host模式如下图所示:
[root@bogon ~]# docker run -tid --net=host --name docker_host1 busybox
245b932232681f82eb927bc32f79181538577b98c44f57c9e43771f8c8547c69
# 使用ifconfig命令可以看到容器的网络和宿主机的是一致的
[root@bogon ~]# docker exec -it docker_host1 sh
/ # ifconfig
br-2171fab71098 Link encap:Ethernet HWaddr 02:42:FD:CB:F4:2E
inet addr:172.18.0.1 Bcast:172.18.255.255 Mask:255.255.0.0
inet6 addr: fe80::42:fdff:fecb:f42e/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:1 errors:0 dropped:0 overruns:0 frame:0
TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:28 (28.0 B) TX bytes:438 (438.0 B)
docker0 Link encap:Ethernet HWaddr 02:42:71:08:11:80
inet addr:172.17.0.1 Bcast:172.17.255.255 Mask:255.255.0.0
inet6 addr: fe80::42:71ff:fe08:1180/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:3192 errors:0 dropped:0 overruns:0 frame:0
TX packets:5240 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:8274623 (7.8 MiB) TX bytes:911741 (890.3 KiB)
ens33 Link encap:Ethernet HWaddr 00:0C:29:6F:A6:FA
inet addr:192.168.207.131 Bcast:192.168.207.255 Mask:255.255.255.0
inet6 addr: fe80::7ef6:a206:d3ad:5f6f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:122622 errors:0 dropped:0 overruns:0 frame:0
TX packets:42535 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:149969818 (143.0 MiB) TX bytes:77332399 (73.7 MiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:72 errors:0 dropped:0 overruns:0 frame:0
TX packets:72 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:6260 (6.1 KiB) TX bytes:6260 (6.1 KiB)
Container模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。 Container模式示意图:
[root@bogon ~]# docker run -tid --name host1 busybox
f4dd88c8a964c228823962f8402df1eb43bda404003899f1ec0dbd4c7a435f82
# 创建host2容器共享host1容器的网络
[root@bogon ~]# docker run -itd --net=container:host1 --name host2 busybox
3cde5380fe5731c074d4ec472117d49760b718884cd4fe36245df852d2e2eaa3
# 查询host1容器的网络
[root@bogon ~]# docker exec -it host1 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:648 (648.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:1
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
# 查看host2容器的网络,确认和host1容器的网络一致
[root@bogon ~]# docker exec -it host2 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:648 (648.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:1
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
None模式
使用none模式,Docker 容器拥有自己的 Network Namespace,但是,并不为Docker 容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。需要我们自己为 Docker 容器添加网卡、配置 IP 等。 None模式示意图:
[root@bogon ~]# docker run -itd --net=none --name none01 busybox sh
c78705a0df04bdfb370c106b24eaba173abdf4cee6ee689eadea46191015548a
[root@bogon ~]# docker exec -it none01 sh
/ # ifconfig
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:1
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)