Host 环境上主要是要通过 Open vSwitch 创建一个虚拟交换机,并且有两个 internal 类型的 port 供虚拟机接入。命令如下:
sudo ovs-vsctl add-br br0
sudo ovs-vsctl add-port br0 tap0 -- set Interface tap0 type=internal
sudo ovs-vsctl add-port br0 tap1 -- set Interface tap0 type=internal
sudo ip link set br0 up
sudo ip link set tap0 up
sudo ip link set tap1 up
sudo ifconfig br0 192.168.3.1/24
192.168.3.0/24 dev enp0s8 proto kernel scope link src 192.168.3.2 metric 101
删除并重新创建:
sudo ip link set br0 up
sudo ip route del 192.168.3.0/24 dev enp0s8 proto kernel scope link src 192.168.3.2 metric 101
sudo ip route add 192.168.3.0/24 dev br0 proto kernel scope link src 192.168.3.2 metric 101
这个时候,我们可以测试一下,虚拟机到容器 c1 是否能够直接通信:
ping -c 3 192.168.3.21
PING 192.168.3.21 (192.168.3.21) 56(84) bytes of data.
64 bytes from 192.168.3.21: icmp_seq=1 ttl=64 time=1.11 ms
64 bytes from 192.168.3.21: icmp_seq=2 ttl=64 time=0.078 ms
64 bytes from 192.168.3.21: icmp_seq=3 ttl=64 time=0.067 ms
再测试一下宿主机到容器的通信
ping -c 3 192.168.3.21
PING 192.168.3.21 (192.168.3.21): 56 data bytes
64 bytes from 192.168.3.21: icmp_seq=0 ttl=64 time=0.740 ms
64 bytes from 192.168.3.21: icmp_seq=1 ttl=64 time=0.622 ms
64 bytes from 192.168.3.21: icmp_seq=2 ttl=64 time=0.605 ms
再测试一下容器到宿主机之间的通信:
docker exec -it c1 sh -c "ping -c 3 192.168.3.1"
PING 192.168.3.1 (192.168.3.1): 56 data bytes
64 bytes from 192.168.3.1: seq=0 ttl=64 time=0.768 ms
64 bytes from 192.168.3.1: seq=1 ttl=64 time=0.632 ms
64 bytes from 192.168.3.1: seq=2 ttl=64 time=0.680 ms
这里其实有个比较容器忽略的地方(对于我来说),就是虚拟机的网卡需要打开混杂(promiscuous) 模式。不然当流向 192.168.3.21 的包进到虚拟机的时候,虚拟机网卡发现 mac 地址不是自己的,就会直接抛弃。这个模式我是在上面提供的 Vagrantfile 中打开了。如果实验的时候发现有问题,可以往这个方向多多考虑。接着,我们用同样的方式启动第二台虚拟机即可。
最后测试两台vm上容器和容器之间的通信:
docker exec -it c1 sh -c "ping -c 3 192.168.3.31"
PING 192.168.3.31 (192.168.3.31): 56 data bytes
64 bytes from 192.168.3.31: seq=0 ttl=64 time=0.825 ms
64 bytes from 192.168.3.31: seq=1 ttl=64 time=0.796 ms
64 bytes from 192.168.3.31: seq=2 ttl=64 time=0.566 ms