1. 程式人生 > 實用技巧 >docker虛擬ip和專案地ip衝突問題解決

docker虛擬ip和專案地ip衝突問題解決

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

而專案地網段是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通訊原理,給我講了一下大概為什麼會這樣。

地址: 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網路隔離的文章看看