Docker容器网络实操教程( 三 )

但是,也ping不同通netns1
ping -c 2 172.18.0.20PING 172.18.0.20 (172.18.0.20) 56(84) bytes of data.From 172.18.0.10 icmp_seq=1 Destination Host UnreachableFrom 172.18.0.10 icmp_seq=2 Destination Host Unreachable--- 172.18.0.20 ping statistics ---2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 63mspipe 2显然有问题了,netns1 ping不同根命名空间 。由于两个容器都位于同一IP网络中172.18.0.0/16,所以可以用veth1和netns0容器与主机进行对话 。什么导致以上问题呢?对问题出在路由冲突了!
检查根命名空间中的路由表:
ip route172.18.0.0/16 dev veth0 proto kernel scope link src 172.18.0.11172.18.0.0/16 dev veth1 proto kernel scope link src 172.18.0.21在添加了第二veth对之后,根网络堆栈也添加新路由172.18.0.0/16 dev veth1 proto kernel scope link src 172.18.0.21,但这和已有的路由冲突了 。如果删除第一条路由sudo ip route delete 172.18.0.0/16 dev veth0 proto kernel scope link src 172.18.0.11并重新检查连接性,netns1将恢复连接的连通性,netns0会处于不确定状态 。

Docker容器网络实操教程

文章插图
 
线上用上述方法,veth行不通了 。这是就需要另外的可行方法了 。这方法就是Linux网桥,另外一个虚拟化网络工具 。Linux网桥的行为上类似于网络交换机 。它在与其连接的接口之间转发数据包 。并且由于它是交换机,因此可以在L2(即以太网)级别上进行操作 。我们就来尝试网桥来建容器网络,先清空之前的网络命名空间:
sudo ip netns delete netns0sudo ip netns delete netns1sudo ip link delete veth0sudo ip link delete ceth0sudo ip link delete veth1sudo ip link delete ceth1快速重新创建两个容器 。
sudo ip netns add netns0sudo ip link add veth0 type veth peer name ceth0sudo ip link set veth0 upsudo ip link set ceth0 netns netns0sudo nsenter --net=/var/run/netns/netns0ip link set lo upip link set ceth0 upip addr add 172.18.0.10/16 dev ceth0sudo ip netns add netns1sudo ip link add veth1 type veth peer name ceth1sudo ip link set veth1 upsudo ip link set ceth1 netns netns1sudo nsenter --net=/var/run/netns/netns1ip link set lo upip link set ceth1 upip addr add 172.18.0.20/16 dev ceth1确保主机上没有新路由:
ip routedefault via 10.0.2.2 dev eth0 proto dhcp metric 10010.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 metric 100最后,创建网桥接口:
sudo ip link add br0 type bridgesudo ip link set br0 up附加veth0和veth1到网桥br0:
sudo ip link set veth0 master br0sudo ip link set veth1 master br0新的网络拓扑图:
Docker容器网络实操教程

文章插图
 
检查容器之间的连通性:
sudo nsenter --net=/var/run/netns/netns0ping -c 2 172.18.0.20PING 172.18.0.20 (172.18.0.20) 56(84) bytes of data.64 bytes from 172.18.0.20: icmp_seq=1 ttl=64 time=0.259 ms64 bytes from 172.18.0.20: icmp_seq=2 ttl=64 time=0.051 ms--- 172.18.0.20 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 2msrtt min/avg/max/mdev = 0.051/0.155/0.259/0.104 mssudo nsenter --net=/var/run/netns/netns1ping -c 2 172.18.0.10PING 172.18.0.10 (172.18.0.10) 56(84) bytes of data.64 bytes from 172.18.0.10: icmp_seq=1 ttl=64 time=0.037 ms64 bytes from 172.18.0.10: icmp_seq=2 ttl=64 time=0.089 ms--- 172.18.0.10 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 36msrtt min/avg/max/mdev = 0.037/0.063/0.089/0.026 msOK!一切正常 。这种方法可行 。由于还没有配置veth0和veth1 。分配给ceth0和ceth1两个IP地址 。由于它们都在同一以太网段上(请记住,我们已将它们连接到虚拟交换机),因此在L2级别具有连通性:
sudo nsenter --net=/var/run/netns/netns0ip neigh172.18.0.20 dev ceth0 lladdr 6e:9c:ae:02:60:de STALE 
sudo nsenter --net=/var/run/netns/netns1ip neigh172.18.0.10 dev ceth1 lladdr 66:f3:8c:75:09:29 STALE容器链接外网(IP路由和伪装)现在容器可以互通互联 。但是与主机(即根命名空间)还不能连通:
sudo nsenter --net=/var/run/netns/netns0ping 10.0.2.15 # eth0 addressconnect: Network is unreachable查看路由:
ip route172.18.0.0/16 dev ceth0 proto kernel scope link src 172.18.0.10根命名空间无法与容器无路由:
ping -c 2 172.18.0.10PING 172.18.0.10 (172.18.0.10) 56(84) bytes of data.From 213.51.1.123 icmp_seq=1 Destination Net UnreachableFrom 213.51.1.123 icmp_seq=2 Destination Net Unreachable--- 172.18.0.10 ping statistics ---2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 3ms


推荐阅读