方案原理分析
由於使用容器的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