Docker網(wǎng)絡(luò)IP地址沖突的解決方法
這個問題其實稍微有一點(diǎn)點(diǎn)麻煩,網(wǎng)上也沒有看到有比較全面正確的文章, 值得單獨(dú)寫一篇記錄一下。
一、前置知識
因為交換機(jī)的能力有限制,以及網(wǎng)線的連接不可能無限長, 所以我們不可能把所有的主機(jī)都連到同一個交換機(jī)上,然后處于同一個二層網(wǎng)絡(luò)中。
就算能,主機(jī)間的 ARP 廣播也會讓這個網(wǎng)絡(luò)瞬間癱瘓。
所以我們得把主機(jī)拆分到一個個的小的子網(wǎng)里,然后通過路由器再并成三層網(wǎng)絡(luò)。
我們俗稱的 IP 地址其實由兩個部分組成,網(wǎng)絡(luò)地址和主機(jī)地址。 比如 10.0.0.1/8
中,第一個 10
是網(wǎng)絡(luò)地址,后面的 0.0.1
是主機(jī)地址。 那我怎么知道怎么去拆分這兩段呢?靠的就是子網(wǎng)掩碼,也就是那個 /8
。
IP 其實是由 32 位的二進(jìn)制組成的,x.x.x.x
只是為了方便人類閱讀將其轉(zhuǎn)成了十進(jìn)制。 有個簡單粗暴的辦法就是可以認(rèn)為每一段都是 8 位,所以 /8
就代表第一段是網(wǎng)絡(luò)地址。
同理,/16
就代表前兩段都是網(wǎng)絡(luò)地址,10.0.0.0/16
中, 網(wǎng)絡(luò)地址是 10.0
,后兩位 0.0
代表每個子網(wǎng)中的主機(jī)地址。
比如 10.0.0.1/16
和 10.0.0.2/16
是同一個子網(wǎng)的兩個主機(jī)。 10.0.0.1/16
和 10.1.0.1/16
是不同的子網(wǎng)的兩個主機(jī)。
這里只是簡單粗暴的介紹下,更多的信息還是自己去查資料了解學(xué)習(xí)。
二、問題表現(xiàn)
- docker 進(jìn)程無法啟動
- 容器端口無法訪問,抓包顯示為有入站但是沒有出站
三、排查
此處針對的是 dockerd 無法啟動的情況,如果 dockerd 能啟動,可以直接跳到“解決”一節(jié)
首先是看下日志
systemctl status docker journalctl -u docker dmesg | grep docker
一般能看到如下日志:
docker0: link is not ready docker_gwbridge: link is not ready
或者更簡單的排查方法,直接手動啟動 dockerd 看看。 啟動方法可以通過 grep ExecStart /usr/lib/systemd/system/docker.service
查看,
一般來說按如下執(zhí)行就行:
/usr/bin/dockerd --debug
然后能看到最后輸出:
INFO[2021-07-29T02:25:55.811673622Z] stopping event stream following graceful shutdown error="<nil>" module=libcontainerd namespace=moby
failed to start daemon: Error initializing network controller: list bridge addresses failed: PredefinedLocalScopeDefaultNetworks List: [10.252.0.0/24 10.252.1.0/24 10.252.2.0/24]: no available network
這時候可以看下 ip addr
,是否有 docker0
和 docker_gwbridge
,
如果發(fā)現(xiàn)沒有 docker0
,那基本可以肯定是 docker0 無法創(chuàng)建導(dǎo)致 dockerd 啟動失敗了。
四、解決
1、找到占用的網(wǎng)段
默認(rèn)的 docker0 網(wǎng)段是 172.17.0.0/16
,docker_gwbridge 網(wǎng)段是 172.18.0.0/24
,你需要確認(rèn)下這兩個網(wǎng)段是否被占用了。
最簡單的方法就是 ping 一下,如果無響應(yīng)的話,那么就說明沒有被占用。
其次就是看一下本機(jī)的路由表 route -n
,確認(rèn)一下有沒有沖突的段。 一般來說,你會發(fā)現(xiàn)相關(guān)網(wǎng)段要么已經(jīng)被占用,要么是路由表里存在沖突。
案例
比如在我的環(huán)境里,我給 docker0 配置為 10.252.0/24
,然后 dockerd 起不來。
排查后發(fā)現(xiàn) route -n
里有這么一條:
10.0.0.0 172.21.0.1 255.0.0.0 UG 0 0 0 eth0
也就是說 10/8
被占用了,導(dǎo)致和我的 10.252.0/24
沖突。 后來聯(lián)系網(wǎng)管刪除了這條 10/8
的路由后解決。
2、修改 docker 占用的網(wǎng)段
以下操作需要先停止 docker 進(jìn)程
systemctl stop docker
如果你用 docker service,那么 docker 會占用四個網(wǎng)段:
- docker0
- docker_gwbridge
- ucp(docker engine 占用,不常見)
- ingress
其中前三個的網(wǎng)段可以通過配置文件配置,第四個只能手動創(chuàng)建。
前三個網(wǎng)段會讀取 /etc/docker/daemon.json
這個配置文件, 這個文件默認(rèn)是沒有的,需要手動創(chuàng)建。
{ "bip": "", "default-address-pools": [ {"base": "10.252.0.0/24", "size": 24}, {"base": "10.252.1.0/24", "size": 24}, {"base": "10.252.2.0/24", "size": 24} ] }
注意這個 default-address-pools
至少要有兩項,按順序依次為:
- docker0
- docker_gwbridge
- ucp
以防萬一的話,配置三個是最好的??。
接下來是修改 ingress,這個比較麻煩,需要手動創(chuàng)建。
我的辦法是在初始化 docker swarm 以后,啟動 docker stack/service 以前,執(zhí)行以下腳本:
- 刪除 ingress
- 刪除 my-ingress(不一定存在,不存在就忽略)
- 新建 my-ingress
yes 'y' | docker network rm ingress yes 'y' | docker network rm my-ingress 2>&1 | true docker network create \ --driver overlay \ --ingress \ --subnet=10.252.3.0/24 \ # 指定 ingress 的網(wǎng)段,不要和上面 daemon.json 的網(wǎng)段沖突 --gateway=10.252.3.2 \ --opt com.docker.network.driver.mtu=1200 \ my-ingress
ingress 是默認(rèn)名,之所以新建一個名字不一樣的,是因為刪除 ingress 是異步的。 如果你刪除 ingress 后立刻新建一個也叫 ingress 的網(wǎng)絡(luò),很可能會報一個重名的錯誤。
重啟 docker 前,最好先清理一下 docker 的緩存:
ip link del dev docker0 ip link del dev docker_gwbridge rm -rf /var/lib/docker/network
3、另一種粗糙簡單的解決辦法
另一種粗糙簡單的解決辦法就是干脆直接手動創(chuàng)建一個 docker0。
這種解決方法最簡單,但是機(jī)器 reboot 后 docker0 會自動被刪掉, 所以這方法并不持久。
而且,實際上也不一定能解決網(wǎng)段沖突的問題,只是說 docker 能啟動了而已。
ip link add name docker0 type bridge ip addr add dev docker0 10.252.0.1/24
到此這篇關(guān)于Docker網(wǎng)絡(luò)IP地址沖突的解決方法的文章就介紹到這了,更多相關(guān)Docker網(wǎng)絡(luò)IP地址沖突內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
docker網(wǎng)絡(luò),docker-compose?network問題
這篇文章主要介紹了docker網(wǎng)絡(luò),docker-compose?network問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01docker拉取鏡像報錯:Error?response?from?daemon:?Get?“https://r
今天做完一個新項目,搭建了一個新的虛擬機(jī),打算使用docker來搭建各種環(huán)境,發(fā)現(xiàn)拉取鏡像報錯Error?response?from?daemon:?Get?"https://registry-1.docker.io/v2/":?dial?tcp,所以接下來給大家介紹了docker拉取鏡像報錯的解決過程,需要的朋友可以參考下2024-08-08docker部署Minio報錯:Fatal glibc error:CPU does&nb
在CentOS 7上使用Docker部署Minio時遇到CPU不支持問題,通過研究確定是版本太新,由于項目經(jīng)費(fèi)有限,決定降級到CentOS 7,步驟包括拉取Minio鏡像、創(chuàng)建目錄、開放端口和運(yùn)行2024-12-12