docker虚拟ip和项目地ip冲突问题解决

问题描述:

今天项目地的实施跟我说,有两台服务器部署的服务用项目地的内网访问,访问不了(ping都ping 不通),而用vpn来连接却是可以,网管也看过了,发现不了问题。

项目地是用docker swarm来部署的。总共有4台服务器 分别是: 192.168.54.53192.168.54.54192.168.54.57192.168.54.5857是集群的主节点。 5354这两台服务器ping不通, 5758可以ping通也可以访问。

最后通过查询docker的网络


docker network ls
docker inspect docker_gwbridge

发现,5354的docker_gwbridge这个网段是172.18.0.1

docker部署keepalived双虚拟IP docker 虚拟网卡与ip冲突_服务器

而项目地网段是172.18.171.1。 我心想网段的前两位相同,但是第三位不同,应该不存在ip冲突吧。

再看看5758这两台服务器的docker_gwbridge,结果发现都是172.16.0.1网段。我看了一下53和54的装的服务其实不多。就把53的退出了docker swarm 集群,并且把docker_gwbridge删除。

docker swarm leave --force     退出集群
docker  node rm docker_gwbridge        删除docker_gwbridge网络

最后发现学校局域网可以ping通53了。

原理分析:

去跟同事讨论了一波。我同事说他写了一篇HTTP和IP通信原理,给我讲了一下大概为什么会这样。

通过命令 route -n , 看到网络层的ip路由表

docker部署keepalived双虚拟IP docker 虚拟网卡与ip冲突_服务器_02

从下往上一个一个的做路由筛选,我要ping项目地的一台电脑ip: 172.18.171.251

第一:用172.18.171.251 和 最下面的genmask: 255.255.255.0 做与操作得到的是结果是:172.18.171.0 和 192.168.54.0不一致,继续往上走

第二: 用172.18.171.251 和 最倒数第二个的genmask:255.255.0.0 做与操作得到的是结果是:172.18.0.0和172.18.0.0一摸一样,所以他会走docker_gwbridge这个网关。

所以这就解析了为什么ip前两位相同也会造成IP冲突了

更加快捷确定问题的方法:

输入 arp -a 查看链路层协议:

docker部署keepalived双虚拟IP docker 虚拟网卡与ip冲突_服务器_03

这里就可以很清晰的看到ping的时候走的是哪个网关了。就能很快的确定了docker和项目地网络是否ip冲突了

问题解决:

指定docker_gwbridge的ip网段和学校的ip网段不一致就能解决问题了,然后再让该机器重新加入到集群里

docker network create \
--subnet 172.21.0.0/20 \
--gateway 172.21.0.1 \
-o com.docker.network.bridge.enable_icc=false \
-o com.docker.network.bridge.name=docker_gwbridge \
docker_gwbridge

docker_gwbridge解析

docker_gwbridge: 容器收发南北向报文的网络。他在本质上还是一个local的bridge网络,但是他是我们实现多个host之间的container通信的基础。通常情况下,当我们在链接swarm nodes的时候,docker_gwbridge网络就会被在每一个swarm节点上自动创建出来

在容器里使用traceroute baidu.com 这个命令可以查看,网络到baidu.com的路程是怎样的

bash-4.4# traceroute baidu.com
traceroute to baidu.com (39.156.69.79), 30 hops max, 46 byte packets
 1  172.21.0.1 (172.21.0.1)  0.031 ms  0.022 ms  0.020 ms
 2  192.168.54.254 (192.168.54.254)  1.473 ms  1.212 ms  1.125 ms
 3  *  *  *

可以看到会利用172.21.0.1 网卡到宿主机然后再让宿主机到外面的网络,其实docker_gwbridge就给了一个连接到宿主机。我在网上找了副图:

docker部署keepalived双虚拟IP docker 虚拟网卡与ip冲突_docker_04

因为docker网络实现网络隔离,是通过network namespace来管理的,此时想让两个namespace网络连通起来要利用veth pair (Virtual Ethernet Pair),这是一个成对的端口,可以实现上述功能:

docker部署keepalived双虚拟IP docker 虚拟网卡与ip冲突_docker_05

可以安装bridge-utils,去查看宿主机的键值对

yum install bridge-utils
brctl show

结果如下:可以看到veth开头的那些就是veth pair的名字,他们是

[root@ismp ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02424e01b403	no		
docker_gwbridge		8000.02420ae464b2	no		veth279e439
							veth47e8c5c
							veth5f44916
							veth65db808
							veth6b7356d
							veth78717d6
							veth7923c17
							veth93615a9
							vetha391c05
							vethcd7ae02
							vethee59ae2

具体的我也说不清楚。大家可以搜一下linux网络隔离的文章看看