在vm2上执行同样的操作,在创建新容器的时候,指定IP地址为172.18.0.3,容器的环境即准备完毕。在vm1上的centos 容器中ping 172.18.0.3,和预期一致,是无法ping通的。
[root@16bbaeaaebfc /]# ping 172.18.0.3 -c 2 PING 172.18.0.3 (172.18.0.3) 56(84) bytes of data. From 172.18.0.2 icmp_seq=1 Destination Host Unreachable From 172.18.0.2 icmp_seq=2 Destination Host Unreachable --- 172.18.0.3 ping statistics --- 2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1000ms pipe 2 [root@16bbaeaaebfc /]# ping 172.18.0.1 -c 2 PING 172.18.0.1 (172.18.0.1) 56(84) bytes of data. 64 bytes from 172.18.0.1: icmp_seq=1 ttl=64 time=0.060 ms 64 bytes from 172.18.0.1: icmp_seq=2 ttl=64 time=0.079 ms --- 172.18.0.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.060/0.069/0.079/0.012 ms
创建VXLAN接口接入docker网桥先来梳理下docker及docker容器在Linux宿主机网络模块中做的操作,梳理清楚之后会发现打通不同宿主机上docker容器的方法非��简单。从宿主Linux系统的视角看操作系统中的网络设备,总结如下:
docker0接口:网桥,在安装完docker后默认被创建,网段是172.17.0.0/16,网桥的默认IP地址为172.17.0.1。
br-xxxx接口:网桥,在创建完自定义docker网络完被创建,网段是被用户指定的172.18.0.0/16,网桥的默认IP地址为172.18.0.1。
vethxxxx接口:veth网络接口,在创建一个具体的docker容器后被创建,如果有N个运行的容器,就会有N个veth网络接口。容器中的eth0接口和宿主机的veth网络接口是一个veth网络对,Linux上的veth接口作为一个端口连接入docker网桥,如docker0或其他自定义网桥。这也是为什么一个宿主机上的docker容器能够默认通信的原因,因为它们创建后就被接入到了同一个网桥上。
为了方便理解,在默认网段172.17.0.0/16中创建2个容器,在自定义网段中上文已经创建了1个docker容器,利用btctl查看网桥及其接口,如下:
# brctl show bridge name bridge id STP enabled interfaces br-3231f89d69f6 8000.02429722a5f9 no veth2fa4c50 docker0 8000.024244e874e8 no vethc7cd982 vethd3d0c18
从上面的输出结果可以看到,默认网桥docker0上,有vethc7cd982和vethd3d0c18两个网络接口接入。在定义网络网桥br-3231f89d69f6一个端口上,veth2fa4c50网络接口接入。这三个veth网络接口分别连接着一个docker容器的eth0网络接口,连接着同一个网桥的veth网络接口vethc7cd982和vethd3d0c18默认二层能通。
有了上面的梳理和本文第一节VXLAN网络接口的基础知识,想必打通不同宿主机上docker容器的方法也比较清晰了。思路就是在两个容器宿主机上各创建一个VXLAN接口,并且将VXLAN接口接入docker网桥的端口上,如下图:
有了VXLAN接口的连接后,从vm1上docker容器发出的包到达docker网桥后,可以从网桥的VXLAN接口出去,从而报文在VETP(VXLAN接口)处被封装成VXLAN报文,再从物理网络上到达对端VETP所在的主机vm2。对端VTEP能正确解包VXLAN报文的话,随后即可将报文通过vm2上的docker网桥送到上层的docker容器中。
具体的配置如下,在vm1上: