刚接触Docker的时候,你是否好奇容器之间是怎么通信的呢?今天我们就一起来认识一下docker的网络吧~
Docker的网络模块是可插拔式的,默认有五种网络模式可以选择。通过docker network ls这个命令来查看本机中所有的网络模式。
[root@VM_0_14_centos ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
c79756cf9cde bridge bridge local
204025a5abbc host host local
9b9024f5ac40 macvlan macvlan local
6478888548d8 none null local
p2e02u1zhn8x overlay overlay swarm
Host模式详解
默认Docker容器运行会分配独立的Network Namespace隔离子系统,基于host模式,容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace,容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。(用的是宿主机的IP,也就是和宿主机共用一个IP地址,host模式不需要加-p进行端口映射,因为和宿主机共享网络IP和端口)
连接到 host 网络的容器共享 Docker host 的网络栈,容器的网络配置与 host 完全一样。可以通过 --network=host
指定使用 host 网络。
[root@www ~]# docker rm -f `docker ps -aq`
b67e41213bfc
[root@www ~]# docker run -itd --net=host centos7-ssh-v1:latest
a0b030bf26338f41c8fa8c47de3cdc7dd9880036640e048bb563e740f567728b
[root@www ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a0b030bf2633 centos7-ssh-v1:latest "/bin/sh -c /usr/sbi?? 5 seconds ago Up 5 seconds laughing_williamson
[root@www ~]# docker inspect a0b030bf2633 | grep -i networkmode
"NetworkMode": "host",
[root@www ~]# docker exec -it a0b030bf2633 /bin/bash
[root@www ~]# ifconfig
br-a68a7681f73a: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.20.0.1 netmask 255.255.0.0 broadcast 172.20.255.255
inet6 fe80::42:b6ff:fed1:6076 prefixlen 64 scopeid 0x20<link>
ether 02:42:b6:d1:60:76 txqueuelen 0 (Ethernet)
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
br-b09178df0a79: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.21.0.1 netmask 255.255.0.0 broadcast 172.21.255.255
inet6 fe80::42:45ff:feff:369d prefixlen 64 scopeid 0x20<link>
ether 02:42:45:ff:36:9d txqueuelen 0 (Ethernet)
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
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:44ff:fea0:1092 prefixlen 64 scopeid 0x20<link>
ether 02:42:44:a0:10:92 txqueuelen 0 (Ethernet)
RX packets 7021 bytes 306134 (298.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7957 bytes 60566091 (57.7 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.179.100 netmask 255.255.255.0 broadcast 192.168.179.255
inet6 fe80::afe7:df8d:107b:abd1 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:93:42:61 txqueuelen 1000 (Ethernet)
RX packets 98616 bytes 117487805 (112.0 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 22452 bytes 2530627 (2.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens37: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.20.2.129 netmask 255.255.255.0 broadcast 172.20.2.255
inet6 fe80::e64a:a3d7:df04:1664 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:93:42:6b txqueuelen 1000 (Ethernet)
RX packets 82168 bytes 46060412 (43.9 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 12879 bytes 1182653 (1.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 1 (Local Loopback)
RX packets 12 bytes 1004 (1004.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 12 bytes 1004 (1004.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
#容器22端口是启动不了的,因为是共享宿主机的22端口的,在容器内要改为6022才可以,然后重新启动ssh
[root@www ~]# vi /etc/ssh/sshd_config
[root@www ~]# cat /etc/ssh/sshd_config | grep -i port | grep -v "#"
Port 6022
[root@www ~]# /usr/sbin/sshd
#在容器里也可以看到宿主机的端口
[root@www ~]# netstat -tpln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:6022 0.0.0.0:* LISTEN 39/sshd
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 ::1:25 :::* LISTEN -
tcp6 0 0 :::6022 :::* LISTEN 39/sshd
[root@www ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
Connecting to 192.168.179.100:6022...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
在容器中可以看到 host 的所有网卡,并且连 hostname 也是 host 的。host 网络的使用场景又是什么呢?
直接使用 Docker host 的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,则可以选择 host 网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host 上已经使用的端口就不能再用了。
Docker host 的另一个用途是让容器可以直接配置 host 网路。比如某些跨 host 的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进行配置,比如管理 iptables等
使用主机模式不需要加-p映射,因为是共用宿主机的端口了,企业一般用的比较少,容易乱套搞晕懵圈,因为你区分不了在容器还是宿主机里面(共享网络,共享主机名)