一、背景
一般需要对外提供服务的Docker容器,我们在启动时后使用-p命令将对外访问端口暴露给外部,例如启动Docker Registry,我们将5000端口映射出来供外部访问:
docker run -d -p 5000:5000 registry
但最近碰到一个非常奇怪的情况:研发组里一个CentOS 7测试环境里部署有Docker Registry,并对外暴露了端口。启动容器后一段时间内都是可以正常工作的,但在不定时间间隔后,外部主机就会出现无法从仓库中拉取镜像的情况,提示TimeOut:
然而在Docker宿主机上访问仓库则可以正常访问:
至于这个问题,只有手动重启出问题的Docker daemon服务后,外部才可以重新访问,但只要再过一段时间又会出现这样的问题。
二、问题排查
碰到这个问题我第一反应就是问组里的人,是不是有人重启过CentOS 7 自己的firewallD了。
因为这台服务器是我配置的,防火墙虽然开着但我已经开启端口访问了,所以肯定不是因为防火墙阻断连接的缘故。但由于这篇文章是篇踩坑排查文档,所以还是把这种情况写出来了
情况一:开着防火墙但没有开放端口
CentOS 7自带并启用了防火墙FirewallD,我们可以通过下面的命令检查FirewallD的状态:
firewall-cmd --state
如果输出的是“not running”则FirewallD没有在运行,且所有的防护策略都没有启动,那么可以排除防火墙阻断连接的情况了。
如果输出的是“running”,表示当前FirewallD正在运行,需要再输入下面的命令查看现在开放了哪些端口和服务:
firewall-cmd --list-ports firewall-cmd --list-services
可以看到当前防火墙只开放了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:惹不起我还躲不起吗)
但每当用户手动重启过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.
并且将不能在启动的容器中访问外部网络,容器对外暴露的端口外部也不能正常访问:
会不会是因为宿主机的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功能会因为其他各种各样的原因失效…
虽然具体造成本次故障的原因现在还没有确凿的证据定位出,但我现在严重怀疑是因为重启网络服务造成的。因为出问题的服务器宿主机上运行着我们研发组正在开发的Web项目,其中有一个功能是修改网卡IP地址,这个功能在修改完网卡IP后,会自动调用下面的命令重启网络服务:
systemctl restart network.service
而重启网络服务正会使Docker daemon服务自动设置的临时启用IP_FORWARD配置失效:
另外因为是程序直接调用命令,所以不会在history命令中留下痕迹。
至于修复方案倒非常简单,只要一行命令就可以了:
echo 'net.ipv4.ip_forward = 1' /usr/lib/sysctl.d/50-default.conf
执行完成后,重启服务器或使用下面的命令从文件中加载配置:
sysctl -p /usr/lib/sysctl.d/50-default.conf
就可以了。
三、小结
Docker daemon服务在启动的时候会帮帮我们调整很多的配置项,比如这次出事儿的IP_FORWARD配置。
Docker daemon启用IP_FORWARD功能是因为Docker容器默认的网络模式(bridge/网桥模式)会给每个容器分配一个私有IP,如果容器需要和外部通信,就需要使用到NAT。NAT需要IP_FORWARD功能支持,否则无法使用。这也解释了为什么会出现在IP_FORWARD功能停用的情况下,使用bridge模式的容器内外均无法访问的情况。
只是在Linux下,出于安全考虑,默认是停用IP_FORWARD功能的,Docker daemon服务在启动时会检查IP_FORWARD功能是否已经启用,如果没有启用的话,Docker daemon会悄无声息的临时启用此功能,然而临时启用的IP_FORWARD功能并不能持久化,会因为其他命令的干扰导致失效。
不过这次的事情告诉了我一个小道理:当出现问题的时候,不要慌,要结合经验大胆的做出假设并验证,治标治本。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 刘德华《劲歌集》24K金碟港版[WAV+CUE][1.2G]
- Faker五冠王什么意思 世界赛五冠王Faker选手介绍
- faker塞拉斯s14决赛什么出装 faker塞拉斯s14决赛出装介绍
- LOLtoc9魔法口令在哪可以找到 2024云顶之弈toc观赛魔法口令兑换码
- 黑鸭子2008《影视经典·珍藏版》试音碟[WAV+CUE]
- 碧娜《温柔吻语2》[WAV+CUE]
- Stravinsky-Symphonies,Volume1-OrquestaSinfonicadeGalicia,DimaSlobodeniouk(2024)[24-
- 外媒评Switch2:向下兼容是关键 但挑战依然存在
- 任天堂提醒:宠物的尿或唾液或会让NS故障 把它放好!
- 《博德3》再创新高 Steam掌机总游玩时长近2000年
- 张玮伽《想你的夜DSD》东升 [WAV+CUE][1G]
- 姚璎格《 粤 24KGOLD》正版低速原抓[WAV+CUE][1G]
- 杨千嬅《如果大家都拥有海》寰亚 [WAV+CUE][998M]
- 孟庭苇.1994-1990-1994钻石精选集2CD(2022环球XRCD限量版)【上华】【WAV+CUE】
- 群星.1998-华纳好情歌精选17首【华纳】【WAV+CUE】