云原生|【云原生|Docker系列3】Docker网络模式详解

前言

Docker 容器和服务如此强大的原因之一是您可以将它们连接在一起,或者将它们连接到非 Docker 工作负载。本文主要介绍Docker的四种网络模式:Brideg模式、Host模式、Container模式、None模式。
列出容器当前网络:
[root@sanxingtongxue ~]# docker network ls NETWORK IDNAMEDRIVERSCOPE e9f64abf8207bridgebridgelocal e1e8a39e210fhosthostlocal c8092bd3f577nonenulllocal

Bridge模式(自定义网络模式演示) docker 的默认?络模式为bridge模式,此模式会为每一个容器分配,设置IP等,并将容器连接到一个docker0 的虚拟网桥,通过docker0 网桥以及iptables nat 表配置与宿主机通信。示例图如下:
云原生|【云原生|Docker系列3】Docker网络模式详解
文章图片

桥接网络演示步骤如下:
1.创建alpine-net网络。您不需要该–driver bridge标志,因为它是默认标志。
docker network create --driver bridge alpine-net

2.创建两个容器。注意–network标志。执行命令时只能连接一个网络docker run。
docker run -dit --name alpine1 --network alpine-net alpine ash docker run -dit --name alpine2 --network alpine-net alpine ash

3.ping命令验证容器之前是否互通。
ping -c 2 alpine2

操作演示如下:
[root@sanxingtongxue ~]#docker network create --driver bridge alpine-net 5cd703a37a83910502d6f4eff1d047c936434a0e77d27125865acfffba49a0e0 [root@sanxingtongxue ~]# docker network ls NETWORK IDNAMEDRIVERSCOPE 5cd703a37a83alpine-netbridgelocal e9f64abf8207bridgebridgelocal e1e8a39e210fhosthostlocal c8092bd3f577nonenulllocal [root@sanxingtongxue ~]#docker network inspect alpine-net [ { "Name": "alpine-net", "Id": "5cd703a37a83910502d6f4eff1d047c936434a0e77d27125865acfffba49a0e0", "Created": "2022-08-10T10:58:28.892947982+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ] [root@sanxingtongxue ~]# docker ps-a CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES 203dcb1d64b9hello:v1"ash"21 seconds agoCreated8000/tcpalpine1 [root@sanxingtongxue ~]# docker rm -f $(docker ps -aq)#删除所有容器 203dcb1d64b9 [root@sanxingtongxue ~]#docker run -dit --name alpine1 --network alpine-net hello:v1 sh 6eee1dd7a27ac9823a8740f330ec2abfc55898e1c39ac5777180ddb6c1a68bee [root@sanxingtongxue ~]#docker run -dit --name alpine2 --network alpine-net hello:v1 sh de43dfe6ba727fede28837e7392b7cbb45615443f1ce8bf8041c43ddd5679ac8 [root@sanxingtongxue ~]# docker ps CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES de43dfe6ba72hello:v1"sh"2 minutes agoUp 2 minutes8000/tcpalpine2 6eee1dd7a27ahello:v1"sh"3 minutes agoUp 3 minutes8000/tcpalpine1 [root@sanxingtongxue ~]# docker container ls CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES de43dfe6ba72hello:v1"sh"2 minutes agoUp 2 minutes8000/tcpalpine2 6eee1dd7a27ahello:v1"sh"3 minutes agoUp 3 minutes8000/tcpalpine1 [root@sanxingtongxue ~]# docker exec -it alpine2 /bin/bash root@de43dfe6ba72:/# ping -c 2 alpine2 bash: ping: command not found root@de43dfe6ba72:/# apt-get update && apt-get install iputils-ping root@de43dfe6ba72:/# ping -c 2 alpine1 PING alpine1 (172.18.0.2) 56(84) bytes of data. 64 bytes from alpine1.alpine-net (172.18.0.2): icmp_seq=1 ttl=64 time=0.081 ms 64 bytes from alpine1.alpine-net (172.18.0.2): icmp_seq=2 ttl=64 time=0.061 ms--- alpine1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1015ms rtt min/avg/max/mdev = 0.061/0.071/0.081/0.010 ms [root@sanxingtongxue ~]# docker exec -it alpine1 /bin/bash root@6eee1dd7a27a:/# ping -c 2 alpine2 PING alpine2 (172.18.0.3) 56(84) bytes of data. 64 bytes from alpine2.alpine-net (172.18.0.3): icmp_seq=1 ttl=64 time=0.059 ms 64 bytes from alpine2.alpine-net (172.18.0.3): icmp_seq=2 ttl=64 time=0.061 ms--- alpine2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1024ms rtt min/avg/max/mdev = 0.059/0.060/0.061/0.001 ms [root@sanxingtongxue ~]# docker network inspect alpine-net [ { "Name": "alpine-net", "Id": "5cd703a37a83910502d6f4eff1d047c936434a0e77d27125865acfffba49a0e0", "Created": "2022-08-10T10:58:28.892947982+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "6eee1dd7a27ac9823a8740f330ec2abfc55898e1c39ac5777180ddb6c1a68bee": { "Name": "alpine1", "EndpointID": "06f1c1f638f6d12a064d5738e45671cf613c6c38f3c5ae90c8c3480d9655be89", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" }, "de43dfe6ba727fede28837e7392b7cbb45615443f1ce8bf8041c43ddd5679ac8": { "Name": "alpine2", "EndpointID": "be79f2f3d29870455b3faa40d8bf3b483bef0a6f0b32aaa43473f670e94ea5da", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]

官网参考:https://docs.docker.com/network/network-tutorial-standalone/
Host模式 容器不会虚拟出自己的网卡,配置主机的IP等,而是使用宿主机的IP和端口。此时映射的端口可能会生产冲突,但是容器的其余部分(文件系统、进程等)依然是隔离的,此时容器与宿主机共享网络。示例图如下:
云原生|【云原生|Docker系列3】Docker网络模式详解
文章图片

演示步骤如下:
1.创建并启动容器作为分离的进程。该–rm选项意味着一旦容器退出/停止就将其移除。该-d标志意味着启动容器分离(在后台)。
docker run --rm -d --network host --name my_nginx nginx

2.通过浏览 http://localhost:80/访问 Nginx 。
3.使用以下命令检查您的网络堆栈:
检查所有网络接口并确认没有创建新的。
ip addr show

使用命令验证哪个进程绑定到端口 80 netstat。您需要使用sudo该进程,因为该进程归 Docker 守护程序用户所有,否则您将无法看到其名称或 PID。
sudo netstat -tulpn | grep :80

4.停止容器。它将在使用该–rm选项启动时自动删除。
docker container stop my_nginx

操作演示如下:
[root@sanxingtongxue ~]#docker run --rm -d --network host --name myhost_net hello:v1 7c1a1e03b12e30504fb3bd2f0f814209ac9d65cac525a2475eb40f36e34b97ef [root@sanxingtongxue ~]# route -n Kernel IP routing table DestinationGatewayGenmaskFlags Metric RefUse Iface 0.0.0.0172.19.63.2530.0.0.0UG10000 eth0 10.88.0.00.0.0.0255.255.0.0U000 cni-podman0 172.17.0.00.0.0.0255.255.0.0U000 docker0 172.18.0.00.0.0.0255.255.0.0U000 br-5cd703a37a83 172.19.0.00.0.0.0255.255.192.0U10000 eth0 [root@sanxingtongxue ~]# docker ps CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES 7c1a1e03b12ehello:v1"/bin/sh -c 'flask r…"About a minute agoUp About a minutemyhost_net de43dfe6ba72hello:v1"sh"33 minutes agoUp 33 minutes8000/tcpalpine2 6eee1dd7a27ahello:v1"sh"35 minutes agoUp 22 minutes8000/tcpalpine1 [root@sanxingtongxue ~]# ip addr show 1: lo: 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: mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 00:16:3e:02:b2:a8 brd ff:ff:ff:ff:ff:ff inet 172.19.55.145/18 brd 172.19.63.255 scope global dynamic noprefixroute eth0 valid_lft 291075677sec preferred_lft 291075677sec inet6 fe80::216:3eff:fe02:b2a8/64 scope link valid_lft forever preferred_lft forever 3: cni-podman0: mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 4a:22:90:68:12:aa brd ff:ff:ff:ff:ff:ff inet 10.88.0.1/16 brd 10.88.255.255 scope global cni-podman0 valid_lft forever preferred_lft forever inet6 fe80::4822:90ff:fe68:12aa/64 scope link valid_lft forever preferred_lft forever 6: docker0: mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:f4:92:1b:07 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:f4ff:fe92:1b07/64 scope link valid_lft forever preferred_lft forever 87: br-5cd703a37a83: mtu 1500 qdisc noqueue state UP group default link/ether 02:42:32:ab:05:e0 brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 brd 172.18.255.255 scope global br-5cd703a37a83 valid_lft forever preferred_lft forever inet6 fe80::42:32ff:feab:5e0/64 scope link valid_lft forever preferred_lft forever 93: vethf2c72a3@if92: mtu 1500 qdisc noqueue master br-5cd703a37a83 state UP group default link/ether b2:ec:15:6d:d0:b5 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet6 fe80::b0ec:15ff:fe6d:d0b5/64 scope link valid_lft forever preferred_lft forever 95: veth16a58ea@if94: mtu 1500 qdisc noqueue master br-5cd703a37a83 state UP group default link/ether 7a:f3:e8:c2:ba:2b brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::78f3:e8ff:fec2:ba2b/64 scope link valid_lft forever preferred_lft forever [root@sanxingtongxue ~]# sudo netstat -tulpn | grep :80 tcp00 0.0.0.0:80000.0.0.0:*LISTEN552059/python3 tcp600 :::801:::*LISTEN513791/java tcp600 127.0.0.1:8005:::*LISTEN513791/java

云原生|【云原生|Docker系列3】Docker网络模式详解
文章图片

Container模式 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP,端口范围。 kubernetes 中的pod就是多个容器共享一个 Network namespace。同样,两个容器除了?络??,其他的如?件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo ?卡设备通信。示例图如下:
云原生|【云原生|Docker系列3】Docker网络模式详解
文章图片

操作演示如下:
[root@sanxingtongxue ~]# docker run -tid --net=container:alpine1 --name docker_con hello:v1 0eb9f3fac30d6b979b5138816e633abaa80ee6301b1b12b8f1dde7fd583cf998 [root@sanxingtongxue ~]# docker exec -it docker_con /bin/bash root@6eee1dd7a27a:/# apt-get update root@6eee1dd7a27a:/# apt-get install net-tools root@6eee1dd7a27a:/# ifconfig -a eth0: flags=4163mtu 1500 inet 172.18.0.2netmask 255.255.0.0broadcast 172.18.255.255 ether 02:42:ac:12:00:02txqueuelen 0(Ethernet) RX packets 2413bytes 4444758 (4.4 MB) RX errors 0dropped 0overruns 0frame 0 TX packets 1924bytes 176355 (176.3 KB) TX errors 0dropped 0 overruns 0carrier 0collisions 0lo: flags=73mtu 65536 inet 127.0.0.1netmask 255.0.0.0 looptxqueuelen 1000(Local Loopback) RX packets 56bytes 5130 (5.1 KB) RX errors 0dropped 0overruns 0frame 0 TX packets 56bytes 5130 (5.1 KB) TX errors 0dropped 0 overruns 0carrier 0collisions 0root@6eee1dd7a27a:/# route -n Kernel IP routing table DestinationGatewayGenmaskFlags Metric RefUse Iface 0.0.0.0172.18.0.10.0.0.0UG000 eth0 172.18.0.00.0.0.0255.255.0.0U000 eth0

None模式 使用none模式,Docker 容器拥有自己的Network Namespace但不进行任何网络配置。
示例图如下:
云原生|【云原生|Docker系列3】Docker网络模式详解
文章图片

操作演示如下:
[root@sanxingtongxue ~]# docker run -tid --net=none --name docker_none hello:v1 b97b13864a0a8230a979b712e7676cd82a901105d54e390197f36413c9708f90

小拓展 Bridge
网桥是工作在 TCP/IP 二层协议 的虚拟网络设备,与现实世界中的交换机功能相似。与其他虚拟网络设备一样,可以配置 IP、MAC。Bridge 的主要功能是在多个接入 Bridge 的网络接口间转发数据包。如下图,Bridge (设备名 br0) 充当主设备,连接了四个从设备,分别是 tap1,tap2,veth1,eth0。
云原生|【云原生|Docker系列3】Docker网络模式详解
文章图片

虚拟网卡接口VETH
VETH (virtual Ethernet) 设备总是成对出现,彼此相连。 一个设备从协议栈读取数据后,会将数据发送到另一个设备上去。VETH 可以用于两个 namespace 间的网络通信。如果 VETH 设备对中有一个设备不可用,则整个链路也不可用。
【云原生|【云原生|Docker系列3】Docker网络模式详解】云原生|【云原生|Docker系列3】Docker网络模式详解
文章图片

云原生|【云原生|Docker系列3】Docker网络模式详解
文章图片

落红不是无情物,化作春泥更护花。

    推荐阅读