一次 docker 容器无法启动的异常排查

in 工作记录 with 0 comment

错误信息

Failed to Setup IP tables: Unable to enable SKIP DNAT rule

Failed to Setup IP tables: Unable to enable SKIP DNAT rule:  (iptables failed: iptables --wait -t nat -I DOCKER -i br-00477259fd83 -j RETURN: iptables: No chain/target/match by that name.
 (exit status 1))

这是 有一个生产环境需要增加服务,编辑好 docker-compose 后
docker-compose up的时候报出的错误!

image.png

Failed to Setup IP tables: Unable to enable SKIP DNAT rule

简单分析下: 大概是未能设置IP tables 不能去启动 跳过 规则… 没有匹配 %$-! 的Name ...

先去查了下 遇到了比较有意义的帖子 :

https://github.com/moby/moby/issues/16816#issuecomment-179717327
https://github.com/moby/moby/issues/16816

看上去和 linux 防火墙 和 iptables.rule 有关

Firewalld只是一个操作iptables的工具,你在firewalld配置的规则最终还是写进了iptables里。

Firewall 和 iptables 具体细节我也不太理解,这里我只是简单理解为和windows功能差不多的防火墙。

初步分析

之前基本都是阿里云主机,本机防火墙一般都关闭,靠阿里云提供的端口策略开启关闭端口,但是这次的是客户的机子,应该是启动了防火墙的。

查看了下本机的Firewall 和 iptables的状态。

systemctl status firewalld
service iptables status

firewalld 是开启的,iptables status 看到是关闭的,关闭时间是3个月前。

image.png

iptables 3个月前关闭这个我比较诧异,看其他Docker服务的运行时间,都是7个月前启动的.. 结合前面的信息我觉得和iptables很有可能有关系。

定位具体问题

很多人对这个问题的建议是重启Docker服务就能恢复,但是这台机子有其他的服务,重启守护进程会造成业务中断,而且万一也起不来,那可就玩大了,糟心的事就在这里,于是我需要其他的解决办法。

首先错误可能是iptables服务发生改变引起的,先排除影响范围,既然docker-compose up出错,其他的指令呢?

先试试Docker run, 跑个Hello World

docker run hello-world

运行成功!

image.png

docker run 和 docker-compose 底层运行原理应该是一样的,为什么run就可以启动?

想到这里我再次查看了 docker-compose.yml文件,联想到报错应该是和网络这边有关,docker虚拟网卡? yml中我未指定任何网卡, 按道理docker-compose会自动创建新的 一个default 网卡的, 而run用的是默认的 bridge网卡,是不用新建立网卡的。

想到这里, 我将docker-compose.yml中的容器都指定为:

network_mode: "host"

这是用本地模式,启动成功了! 换成其他虚拟网卡也可以!

看来 iptables改变,只是影响了新建立虚拟网卡而已, 顺利的启动了服务,问题也到这里结束了,重启真的会好吗? 我也不得而知.. 毕竟复现这个问题太麻烦了。

参考文章:

https://github.com/moby/moby/issues/16816#issuecomment-179717327
https://github.com/moby/moby/issues/16816
https://www.cnblogs.com/grimm/p/10345693.html
https://www.timeit.cn/post-326.html