方案原理分析
由于使用容器的IP进行路由,就需要避免不同主机上的容器使用了相同的IP,为此我们应该为不同的主机分配不同的子网来保证。于是我们构造一下两个容器之间通信的路由方案,如下图所示。
解析
两台主机:host1的IP:192.168.10.11/24 host2的IP:192.168.10.12/24
设置虚拟网卡docker0的IP分别为172.17.0.1/16与172.18.0.1/16两个网段
两台主机之间容器在创建时会自动分配网段下的IP(如container1的172.17.0.2),主机需要有容器网段的路由表才能转发相应的数据包。
方案实现
分别对主机1和主机2上的docker0进行配置
编辑host1上的 /etc/docker/daemon.json 文件,添加内容:”bip” : “ip/netmask”
{ "bip":"172.17.0.1/16" }
编辑host2上的 /etc/docker/daemon.json 文件,添加内容:”bip” : “ip/netmask”
{"bip":"172.18.0.1/16"}
添加路由规则
host1上添加路由规则如下:(网段172.18.0.0/16的寻址网关在192.168.10.12)
route add -net 172.18.0.0 netmask 255.255.0.0 gw 192.168.10.12
host2上添加路由规则如下:(网段172.17.0.0/16的寻址网关在192.168.10.11)
route add -net 172.17.0.0 netmask 255.255.0.0 gw 192.168.10.11
配置iptables规则
host1上添加如下规则:
iptables -t nat -F POSTROUTING #清理NATPOSTROUTING转发表
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -d 192.168.10.0/24 -j MASQUERADE #对源 IP 为 172.17.0.0/16 ,目标 IP 不为 192.168.10.0/24 的数据包做 IP 伪装,伪装成接口的第一个 IP(即是host1的物理网卡地址)
host2上添加如下规则:
iptables -t nat -F POSTROUTING #清理NATPOSTROUTING转发表
iptables -t nat -A POSTROUTING -s 172.18.0.0/16 ! -d 192.168.10.0/24 -j MASQUERADE #对源 IP 为 172.18.0.0/16 ,目标 IP 不为 192.168.10.0/24 的数据包做 IP 伪装,伪装成接口的第一个 IP(即是host2的物理网卡地址)
启动容器
host1上启动centos容器:
docker run -it --name host1.test centos /bin/bash
host2上启动centos容器:
docker run -it --name host2.test centos /bin/bash
ifconfig查看IP信息
如果没有该命令需要执行安装命令:yum install net-tools -y
host1上的容器IP:
host2上的容器IP:
测试互联
在host1的容器上ping在host2的容器ip。
在host2上抓下包看看ICMP是如何转发的
由此可以知道发向172.18.0.2的ICMP报文都要经过192.168.10.11。
数据包流程:c1-->host1 docker0-->host1 eth网卡-->host2 eth网卡-->host2 docker0-->c2