解决Docker启动时iptables报错问题,不必重启docker服务

  错误日志如下:

  docker: Error response from daemon: driver failed programming external connectivity on endpoint : (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 38067 -j DNAT --to-destination 172.17.0.2:8080 ! -i docker0: iptables: No chain/target/match by that name.

  docker: Error response from daemon: driver failed programming external connectivity on endpoint : (iptables failed: iptables --wait -t filter -A DOCKER ! -i docker0 -o docker0 -p tcp -d 172.17.0.2 --dport 8080 -j ACCEPT: iptables: No chain/target/match by that name.

  在使用docker部署的时候,遇上了iptables报错的问题,截止目前搜索到的前二十个解决方案里几乎全是重启docker服务。

  其实我在写这个解决方案之前也遇见不止一次这个问题,当时的情况是docker服务下的容器数量少,重启docker服务是一种可以接受的解决方案。但是这次不同:服务器上有数十个容器且为不同项目组部署,重启只能作为所有方案失效后的最终方案。

  于是,我将日志发给deepseek,问他有没有在不重启docker服务的情况下的解决方案。deepseek很快给出了方案,虽然没有完全解决,但是提供了解决思路最终解决了问题。以下先说解决过程,再提供deepseek的回复。

  1.重点思路是排查iptables中DOCKER链是否存在,deepseek给出来了nat表恢复DOCKER链的命令。先后重建了nat表和filter表的DOCKER链(其实就是重建nat表规则链后,部署容器失败了,但日志发生了变化,就在filter表重建规则链),容器run起来了。

  2.内核模块先看是否加载,不建议直接去加载。

  3.docker的daemon配置,配置后似乎未生效。

  

  虽然在部署中应该谨慎对待防火墙,但是在隔离环境里真的不想开防火墙。附上炸墙命令,炸墙一时爽,一直炸墙一直爽,安全事故火葬场。

  systemctl stop firewalld && systemctl disable firewalld && iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X

 

针对Docker容器启动时出现的iptables: No chain/target/match by that name错误,可通过以下步骤在不重启Docker服务的情况下解决:

一、核心原因分析

该错误通常由以下原因导致:

DOCKER链缺失‌:nat表中缺少DOCKER链或相关规则链‌;
内核模块未加载‌:br_netfilter等内核模块未加载,导致DNAT规则无法生效‌;
防火墙冲突‌:firewalld或其他防火墙工具与Docker的iptables规则产生冲突‌。
二、具体解决步骤
1. 手动恢复DOCKER链
bash
Copy Code
# 检查nat表中是否存在DOCKER链
iptables -t nat -L DOCKER

# 若不存在,手动创建DOCKER链及相关规则
iptables -t nat -N DOCKER
iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
iptables -t nat -A OUTPUT -m addrtype --dst-type LOCAL -j DOCKER

2. 加载内核模块
bash
Copy Code
# 加载br_netfilter模块(DNAT必需)
modprobe br_netfilter

# 加载nf_nat模块
modprobe nf_nat

# 确认模块加载成功
lsmod | grep -E 'br_netfilter|nf_nat'

3. 检查Docker配置

若系统中同时存在firewalld或其他防火墙工具,需调整Docker配置以避免规则冲突:

bash
Copy Code
# 编辑Docker配置文件
vim /etc/docker/daemon.json

# 添加以下内容(若已存在其他配置,保留并追加)
{
  "iptables": false,
  "experimental": true
}

# 应用配置(无需重启Docker服务)
systemctl reload docker

4. 验证规则生效
bash
Copy Code
# 查看nat表中的DOCKER链
iptables -t nat -L DOCKER --line-numbers

# 检查DNAT规则是否存在
iptables -t nat -L | grep DNAT

三、附加说明
防火墙兼容性‌:若使用firewalld,建议通过firewall-cmd放行Docker所需端口,而非直接操作iptables‌;
持久化配置‌:通过/etc/modules-load.d/modules.conf文件确保内核模块开机自动加载‌。

通过以上步骤,可在不重启Docker服务的情况下修复因iptables规则链缺失或内核模块未加载导致的错误‌。

 

 

 

posted @ 2025-03-20 15:58  单亚林  阅读(1913)  评论(0)    收藏  举报