(四)理解容器之间的连通性

通过前面小节的实践,当前 docker host 的网络拓扑结构如下图所示,今天我们将讨论这几个容器之间的连通性。

两个 busybox 容器都挂在 my_net2 上,应该能够互通,我们验证一下:

root@cuiyongchao:~# docker run -it --network my_net2 --ip 172.22.0.88 busybox
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:16:00:58  
          inet addr:172.22.0.88  Bcast:172.22.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:656 (656.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)

/ # ping 172.22.0.1 -c 1
PING 172.22.0.1 (172.22.0.1): 56 data bytes
64 bytes from 172.22.0.1: seq=0 ttl=64 time=0.152 ms
--- 172.22.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.152/0.152/0.152 ms
/ # ping 172.22.0.2 -c 1
PING 172.22.0.2 (172.22.0.2): 56 data bytes
64 bytes from 172.22.0.2: seq=0 ttl=64 time=0.127 ms
--- 172.22.0.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.127/0.127/0.127 ms
/ # 

可见同一网络中的容器、网关之间都是可以通信的。

my_net2 与默认 bridge 网络能通信吗?从拓扑图可知,两个网络属于不同的网桥,应该不能通信,我们通过实验验证一下,让 busybox 容器 ping httpd 容器:

/ # ping 172.17.0.2 -c 1
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
/ # 

​ 确实 ping 不通,符合预期。“等等!不同的网络如果加上路由应该就可以通信了吧?”我已经听到有读者在建议了。

​ 这是一个非常非常好的想法。确实,如果 host 上对每个网络的都有一条路由,同时操作系统上打开了 ip forwarding,host 就成了一个路由器,挂接在不同网桥上的网络就能够相互通信。下面我们来看看 docker host 满不满足这些条件呢?

ip r 查看 host 上的路由表

root@cuiyongchao:~# ip r
default via 10.0.0.254 dev ens33 proto static 
10.0.0.0/24 dev ens33 proto kernel scope link src 10.0.0.20 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 
172.22.0.0/16 dev br-ba21840c1713 proto kernel scope link src 172.22.0.1 

172.17.0.0/16 和 172.22.16.0/24 两个网络的路由都定义好了。再看看 ip forwarding:

# sysctl net.ipv4.ip_forward

net.ipv4.ip_forward = 1

ip forwarding 也已经启用了。

条件都满足,为什么不能通行呢?

我们还得看看 iptables-save:

-A DOCKER-ISOLATION-STAGE-1 -i br-ba21840c1713 ! -o br-ba21840c1713 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-283474cba87c ! -o br-283474cba87c -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o br-ba21840c1713 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o br-283474cba87c -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN

原因就在这里了:iptables DROP 掉了网桥 docker0 与 br-ba21840c1713 之间双向的流量。

从规则的命名 DOCKER-ISOLATION 可知 docker 在设计上就是要隔离不同的 netwrok。

那么接下来的问题是:怎样才能让 busybox 与 httpd 通信呢?答案是:为 httpd 容器添加一块 net_my2 的网卡。这个可以通过docker network connect 命令实现。

root@cuiyongchao:~# docker network connect my_net2 631d88d3f0d9
root@cuiyongchao:~# docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
631d88d3f0d9        httpd               "bash"               23 seconds ago      Up 22 seconds       80/tcp              elated_volhard


我们在 httpd 容器中查看一下网络配置:

root@631d88d3f0d9:/usr/local/apache2# ip a
bash: ip: command not found
root@631d88d3f0d9:/usr/local/apache2# 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 3969  bytes 8864961 (8.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3861  bytes 209797 (204.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.22.0.4  netmask 255.255.0.0  broadcast 172.22.255.255
        ether 02:42:ac:16:00:04  txqueuelen 0  (Ethernet)
        RX packets 12  bytes 936 (936.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

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 2  bytes 171 (171.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2  bytes 171 (171.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


容器中增加了一个网卡 eth1,分配了 my_net2 的 IP 172.22.0.4。现在 busybox 应该能够访问 httpd 了,验证一下:

/ # ping 172.22.0.4 -c 1
PING 172.22.0.4 (172.22.0.4): 56 data bytes
64 bytes from 172.22.0.4: seq=0 ttl=64 time=0.098 ms

--- 172.22.0.4 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.098/0.098/0.098 ms
/ # 

busybox 能够 ping 到 httpd,并且可以访问 httpd 的 web 服务。当前网络结构如图所示:

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/cuiyongchao007/p/14003851.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!