Docker容器频繁遭遇连接中断,原因何在?

2026-05-17 08:361阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1166个文字,预计阅读时间需要5分钟。

一、背景+生产环境与版本:CentOS 8 + Docker 20.0 + MySQL 5.7

二、主机:需要对外提供服务的Docker容器

三、启动后,使用`-p`命令将外部访问端口暴露给外部,例如:启动Docker MySQL,将3306端口暴露给外部。

一、背景

生产环境与版本

主机: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

至此,业务恢复正常。

如果有错误,欢迎各位网友指导。 另外喜欢的话,给个推荐呗,谢谢!
标签:问题

本文共计1166个文字,预计阅读时间需要5分钟。

一、背景+生产环境与版本:CentOS 8 + Docker 20.0 + MySQL 5.7

二、主机:需要对外提供服务的Docker容器

三、启动后,使用`-p`命令将外部访问端口暴露给外部,例如:启动Docker MySQL,将3306端口暴露给外部。

一、背景

生产环境与版本

主机: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

至此,业务恢复正常。

如果有错误,欢迎各位网友指导。 另外喜欢的话,给个推荐呗,谢谢!
标签:问题