How two hosts' dockers communicate with each other

Host list:

192.168.6.132 host name vm132 system centos7

192.168.6.132 host name vm132 system centos7

install docker

wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo
sed -i 's+download.docker.com+mirrors.cloud.tencent.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
yum makecache fast
yum install docker-ce  -y

Configure different network segments for the two hosts

Add the following configuration to /etc/docker/daemon.json of 192.168.6.132 (vm132)

{
  "bip": "172.17.132.1/24",
  ......
}

Add the following configuration to /etc/docker/daemon.json of 192.168.6.136 (vm136)

{
  "bip": "172.17.136.1/24",
  ......
}

Restart the docker service sudo systemctl restart docker

Analysis of the principle of docker access to the external network

Execute on any host:

[root@vm132 ~]# docker run  -itd --name alpine  alpine   #启动一个alpine容器
[root@vm132 ~]# docker exec  -it alpine sh                #进入容器
/ # ping baidu.com                                        #在容器内ping百度是可以ping通的
PING baidu.com (39.156.69.79): 56 data bytes
64 bytes from 39.156.69.79: seq=0 ttl=127 time=43.406 ms

Why can I ping Baidu?

[root@vm132 ~]# iptables -t nat  -L -n
...省略
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  172.17.132.0/24      0.0.0.0/0
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0
...省略

Check the nat table of iptables and find that the source is that the IP of the container network segment performs SNAT when accessing, which is similar to accessing the external network (such as: Baidu) from a LAN.

The process of docker (172.17.132.2) accessing the external network is as follows (SNAT is done):
包出vm132时做了SNAT,  SNAT之后包的源地址就是vm132的IP  
包出路由器时又做了SNAT, SNAT之后包的源地址就是路由器的公网IP

包回到路由器时,根据路由器的conntrack(链接跟踪表),把包的目的IP修改为vm132的IP(因为包出vm132时做了SNAT源IP从docker修改为vm132的IP)
包回到vm132时,根据vm132的conntrack(链接跟踪表),把包的目的IP修改为docker的IP。整体通讯过程打通
If docker accesses the external network without SNAT, the process is as follows.
包出vm132时没做SNAT,  包的源地址就是172.17.132.2
包出路由器时做了SNAT, SNAT之后包的源地址就是路由器的公网IP  (源IP从172.17.132.2修改为路由器公网IP)

包回到路由器时,根据路由器的conntrack(链接跟踪表),把包的目的IP修改为docker的IP。
此时路由器懵了,他只知道各主机的IP,不知道docker的IP在哪儿。通讯失败

View host routing table

[root@vm132 ~]# route -n
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.6.2     0.0.0.0         UG    0      0        0 ens33
172.17.132.0    0.0.0.0         255.255.255.0   U     0      0        0 docker0
192.168.6.0     0.0.0.0         255.255.255.0   U     0      0        0 ens33

If the docker of the vm132 host wants to communicate with the docker of the vm136 host, the destination address is the 172.17.136.0/24 network segment, so the content of the routing table needs to be modified according to the following command. In order to ensure that the docker containers of the two servers can communicate with each other, the hosts of vm132 and vm136 each add a routing table information. Meaning: If the destination IP is the docker of the other host, set the gateway to the other host.

vm132服务器执行下面的命令:
[root@vm132 ~]# route add -net  172.17.136.0/24  gw 192.168.6.136

vm136服务器执行下面的命令:
[root@vm136 ~]# route add -net  172.17.132.0/24  gw 192.168.6.132

Thinking: If only the dockers of two hosts can communicate, is SNAT of iptables needed?
Answer: No need. The reason for using SNAT is that you don’t know who to look for when the packet comes back. The above two routing information can allow the containers of the two servers to find each other, so SNAT is not needed.

But if docker needs to access the external network, SNAT is needed, and the corresponding iptables rules also need to be preserved.

Clear the iptables rules and modify the default rules to ACCEPT

Two hosts operate at the same time, the command is as follows:

iptables   -F
iptables  -t  nat  -F

然后检查有没有默认规则不对的,如有默认规则不是ACCEPT,修改一下,如:
iptables  -P FORWARD  ACCEPT

The dockers of the two hosts can communicate with each other at this time

try it yourself

think:

1、如果2台主机也不在同一网段,主机间的docker要通讯,需要做SNAT不?
2、局域网内k8s中2台主机的docker互相访问如果做了SNAT,容器的日志记录的是各主机的IP合适吗?该怎么办才能使得日志记录的是容器IP。

Guess you like

Origin blog.csdn.net/sinat_24354307/article/details/118464993