Docker容器不定時出現無法連接的問題


一、背景

生產環境與版本

主機:centos8     docker:20.0       mysql:5.7

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

docker run -it -d -p 3376:3306 docker.io/centos:latest /bin/bash

但最近碰到一個非常奇怪的情況:ECS主機中一個CentOS 8生產環境里部署有Docker Mysql,並對外暴露了端口。啟動容器后一段時間內都是可以正常工作的,但在不定時間間隔后,外部主機就會出現無法從訪問的情況:

 

二,問題排查

1、排查端口

碰到此問題問詢開發、運維人員是不是有人重啟過CentOS 8 自己的firewallD了。

查看防火牆的狀態

systemctl status firewalld.service

然后排查對應的端口是否開放

iptables -nL

如果是防火牆問題:解決方案有兩種:

1)關閉FirewallD服務:

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

systemctl stop firewalld.service

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

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

iptables -A INPUT -p tcp --dport 5000 -j ACCEPT

 

2、查看容器日志

命令格式:

$ docker logs [OPTIONS] CONTAINER Options: --details 顯示更多的信息 -f, --follow 跟蹤實時日志 --since string 顯示自某個timestamp之后的日志,或相對時間,如42m(即42分鍾) --tail string 從日志末尾顯示多少行日志, 默認是all -t, --timestamps 顯示時間戳 --until string   顯示自某個timestamp之前的日志,或相對時間,如42m(即42分鍾)

例子:

查看指定時間后的日志,只顯示最后100行:

$ docker logs -f -t --since="2022-04-08" --tail=100 CONTAINER_ID

查看某時間之后的日志:

$ docker logs -t --since="2022-04-08T13:23:37" CONTAINER_ID

經過日志排查,發現容器日志無錯誤日志

 

3、排查網絡

 A:查看容器運行狀態正常如圖:

由上圖可知,容器運行正常。

 

 B:查看容器對外網之間的網絡:

由上圖所知,容器對外網不通

 

C:查看容器與docker0網卡之間網絡

 由上圖所知容器與docker0網卡之間通信正常

 

D:查看容器與宿主機之間網絡

 

 由上圖所知,容器與宿主機之間的通信正常

. Docker容器實例中解析DNS的順序

1) 首先,查找Docker daemon內置的DNS服務器127.0.0.11

2) 其次,查找docker run創建容器實例時通過--dns參數設置的DNS服務器

3) 再次,查找Docker daemon通過--dns參數,或/etc/docker/daemon.json文件設置的DNS服務器

4) 又次,查找Docker宿主機上/etc/resolv.conf文件中配置的DNS服務器

5) 最后,查找Google的DNS服務器,如8.8.8.8和8.8.4.4,2001:4860:4860::8888和2001:4860:4860::8844

4、沒有啟用IP_FORWARD

因為網絡通正常,一直沒法定位出問題的所在,發現不能正常訪問容器時,手動登陸宿主機重啟Docker daemon服務。如果宿主機沒有啟用IP_FORWARD功能,那Docker容器在啟動時會輸出一條警告消息:

WARNING: IPv4 forwarding is disabled. Networking will not work.

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

sysctl net.ipv4.ip_forward

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

可是問題來了,當時啟動容器的時候都是好的啊,什么都沒有輸出,怎么用着用着IP_FORWARD功能就被禁用了呢?Docker daemon服務在啟動的時候會自動設置iptables設置,難不成它還會檢查IP_FORWARD設置,並幫我臨時啟用嗎?

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

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

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

然后使配置生效

sysctl -p

至此,業務恢復正常。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM