docker虛擬ip和項目地ip沖突問題解決
問題描述:
今天項目地的實施跟我說,有兩台服務器部署的服務用項目地的內網訪問,訪問不了(ping都ping 不通),而用vpn來連接卻是可以,網管也看過了,發現不了問題。
項目地是用docker swarm來部署的。總共有4台服務器 分別是: 192.168.54.53
, 192.168.54.54
, 192.168.54.57
, 192.168.54.58
。57
是集群的主節點。 53
和54
這兩台服務器ping不通, 57
和58
可以ping通也可以訪問。
最后通過查詢docker的網絡
docker network ls
docker inspect docker_gwbridge
發現,53
和54
的docker_gwbridge這個網段是172.18.0.1
而項目地網段是172.18.171.1
。 我心想網段的前兩位相同,但是第三位不同,應該不存在ip沖突吧。
再看看57
和58
這兩台服務器的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通信原理,給我講了一下大概為什么會這樣。
地址: https://blog.csdn.net/qq_39294770/article/details/108328572
通過命令 route -n
, 看到網絡層的ip路由表
從下往上一個一個的做路由篩選,我要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
查看鏈路層協議:
這里就可以很清晰的看到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網絡實現網絡隔離,是通過network namespace來管理的,此時想讓兩個namespace網絡連通起來要利用veth pair (Virtual Ethernet Pair),這是一個成對的端口,可以實現上述功能:
可以安裝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網絡隔離的文章看看