亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Docker容器端口映射后突然無法連接如何排查

發布時間:2022-03-24 17:02:14 來源:億速云 閱讀:2834 作者:iii 欄目:web開發

這篇“Docker容器端口映射后突然無法連接如何排查”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Docker容器端口映射后突然無法連接如何排查”文章吧。

一、背景

一般需要對外提供服務的docker容器,我們在啟動時后使用-p命令將對外訪問端口暴露給外部,例如啟動docker registry,我們將5000端口映射出來供外部訪問:

docker run -d -p 5000:5000 registry

但最近碰到一個非常奇怪的情況:研發組里一個centos 7測試環境里部署有docker registry,并對外暴露了端口。啟動容器后一段時間內都是可以正常工作的,但在不定時間間隔后,外部主機就會出現無法從倉庫中拉取鏡像的情況,提示timeout:

Docker容器端口映射后突然無法連接如何排查

然而在docker宿主機上訪問倉庫則可以正常訪問:

Docker容器端口映射后突然無法連接如何排查

至于這個問題,只有手動重啟出問題的docker daemon服務后,外部才可以重新訪問,但只要再過一段時間又會出現這樣的問題。

二、問題排查

碰到這個問題我第一反應就是問組里的人,是不是有人重啟過centos 7 自己的firewalld了。

因為這臺服務器是我配置的,防火墻雖然開著但我已經開啟端口訪問了,所以肯定不是因為防火墻阻斷連接的緣故。但由于這篇文章是篇踩坑排查文檔,所以還是把這種情況寫出來了

情況一:開著防火墻但沒有開放端口

centos 7自帶并啟用了防火墻firewalld,我們可以通過下面的命令檢查firewalld的狀態:

firewall-cmd --state

Docker容器端口映射后突然無法連接如何排查

如果輸出的是“not running”則firewalld沒有在運行,且所有的防護策略都沒有啟動,那么可以排除防火墻阻斷連接的情況了。

如果輸出的是“running”,表示當前firewalld正在運行,需要再輸入下面的命令查看現在開放了哪些端口和服務:

firewall-cmd --list-ports
firewall-cmd --list-services

Docker容器端口映射后突然無法連接如何排查 

可以看到當前防火墻只開放了80/tcp端口、ssh服務(22/tcp)和dhcpv6-client服務,并沒有打開docker容器映射的5000/tcp端口。

解決方案有兩種:

1.關閉firewalld服務:

如果您不需要防火墻,那直接關掉firewalld服務就好了

systemctl stop firewalld.service

2.添加策略對外打開指定的端口:

比如我們現在要打開對外5000/tcp端口,可以使用下面的命令:

firewall-cmd --add-port=5000/tcp --permanent
firewall-cmd --reload

如果只是臨時打開端口,去掉第一行命令中的“--permanent”參數,那么當再次重啟firewalld服務時,本策略將失效。 

情況二:人為重啟centos 7的firewalld服務

firewalld是centos系統在7版本引入的新組件,簡單的說就是iptables的包裝,用于簡化防火墻相關的設置。

然而firewalld和docker相處的并不是特別好,當firewalld啟動(或重新啟動)時,會從iptables中刪除docker鏈,造成docker不能正常工作:

firewalld

centos-7 introduced firewalld, which is a wrapper around iptables and can conflict with docker.

when firewalld is started or restarted it will remove the docker chain from iptables, preventing docker from working properly.

when using systemd, firewalld is started before docker, but if you start or restart firewalld after docker, you will have to restart the docker daemon.

 摘自docker官方文檔《centos - docker documentation》

在centos 7中,如果設置使用systemd開機自啟動docker服務是不會有問題的,因為docker在systemd配置文件中明確注明了“after= firewalld.service”,以保證docker daemon 在firewalld啟動后再啟動。

Docker容器端口映射后突然無法連接如何排查

(docker:惹不起我還躲不起嗎)

但每當用戶手動重啟過firewalld服務之后,firewalld服務會將docker daemon寫入iptables的docker鏈刪除,所以需要手動重新啟動一次docker daemon服務,讓docker daemon服務重建docker鏈。

 不過問了組里另外兩個研發,都說沒有動過。查看了shell的history也沒找到對應的記錄。

這就很奇怪了。不過經過一段時間的蹲點排查之后,我終于發現了一個新的原因:

情況三:沒有啟用ip_forward

因為一直沒法定位出問題的所在,所以我們研發組都是發現不能正常訪問倉庫時,手動登陸宿主機重啟docker daemon服務。

在有一次登錄到宿主服務器上準備重啟docker daemon服務前,我突然想起之前在用docker的時候還碰到過另一個問題:如果宿主機沒有啟用ip_forward功能,那docker容器在啟動時會輸出一條警告消息:

warning: ipv4 forwarding is disabled. networking will not work.

并且將不能在啟動的容器中訪問外部網絡,容器對外暴露的端口外部也不能正常訪問:

Docker容器端口映射后突然無法連接如何排查

Docker容器端口映射后突然無法連接如何排查 

會不會是因為宿主機的ip_forward功能沒有啟用所以才引起的這個故障呢?

sysctl net.ipv4.ip_forward

Docker容器端口映射后突然無法連接如何排查

果然,輸出表示當前系統的ip_forward功能處于停用狀態!

可是問題來了,當時啟動容器的時候都是好的啊,什么都沒有輸出,怎么用著用著ip_forward功能就被禁用了呢?

等等,docker daemon服務在啟動的時候會自動設置iptables設置,難不成它還會檢查ip_forward設置,并幫我臨時啟用嗎?

帶著這個假設,我手動重啟了一下docker daemon服務:

Docker容器端口映射后突然無法連接如何排查

果然,docker daemon服務在啟動過程中會檢查系統的ip_forward配置項,如果當前系統的ip_forward功能處于停用狀態,會幫我們臨時啟用ip_forward功能,然而臨時啟用的ip_forward功能會因為其他各種各樣的原因失效…

雖然具體造成本次故障的原因現在還沒有確鑿的證據定位出,但我現在嚴重懷疑是因為重啟網絡服務造成的。因為出問題的服務器宿主機上運行著我們研發組正在開發的web項目,其中有一個功能是修改網卡ip地址,這個功能在修改完網卡ip后,會自動調用下面的命令重啟網絡服務:

systemctl restart network.service

而重啟網絡服務正會使docker daemon服務自動設置的臨時啟用ip_forward配置失效:

Docker容器端口映射后突然無法連接如何排查

另外因為是程序直接調用命令,所以不會在history命令中留下痕跡。

至于修復方案倒非常簡單,只要一行命令就可以了:

echo 'net.ipv4.ip_forward = 1' >> /usr/lib/sysctl.d/50-default.conf

執行完成后,重啟服務器或使用下面的命令從文件中加載配置:

sysctl -p /usr/lib/sysctl.d/50-default.conf

Docker容器端口映射后突然無法連接如何排查 

以上就是關于“Docker容器端口映射后突然無法連接如何排查”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

麻城市| 郧西县| 靖江市| 上饶市| 南靖县| 伊吾县| 阿拉善左旗| 新河县| 辉县市| 沐川县| 阳西县| 共和县| 南皮县| 连云港市| 贡觉县| 平度市| 重庆市| 鄂伦春自治旗| 百色市| 德江县| 常德市| 鄢陵县| 福鼎市| 炎陵县| 汉源县| 彝良县| 昌乐县| 天台县| 香港| 裕民县| 堆龙德庆县| 子洲县| 罗源县| 略阳县| 建阳市| 兴仁县| 定襄县| 合肥市| 汉川市| 达孜县| 竹北市|