docker虛擬ip和專案地ip衝突問題解決
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網路隔離的文章看看