5

iptables --wait -t nat -A DOCKER...: iptables NO chain/target/match by that name

 3 years ago
source link: https://zhangguanzhang.github.io/2021/03/23/iptables-docker-no-chain/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

iptables --wait -t nat -A DOCKER...: iptables NO chain/target/match by that n...



k8s
字数统计: 626阅读时长: 2 min
 2021/03/23  17  Share

我们内部有套部署的工具, 我们部署的流程是先在部署机器(部署机器可能也是node1 )上用脚本安装好 docker,然后进容器里去起我们部署平台,有个很久的 bug 就是,部署机器上端口映射起容器会有如下报错

iptables --wait -t nat -A DOCKER -p tcp -d 0/8 --dport 8089 -j DNAT --to-destination 172.25.0.2:80 ! -i docker0: iptables NO chain/target/match by that name

排查也很简单,缺少链,添加上即可:

sudo iptables --wait -N DOCKER &>/dev/null || true
sudo iptables --wait -t filter -N DOCKER &>/dev/null || true
sudo iptables --wait -t nat -N DOCKER &>/dev/null || true

或者重启 docker daemon 会在启动的时候加上链。脚本安装 docker 的时候,我们执行了下面的

sudo iptables --wait -P INPUT ACCEPT && \
sudo iptables --wait -F && \
sudo iptables --wait -X && \
sudo iptables --wait -F -t nat && \
sudo iptables --wait -X -t nat && \
sudo iptables --wait -F -t raw && \
sudo iptables --wait -X -t raw && \
sudo iptables --wait -F -t mangle && \
sudo iptables --wait -X -t mangle

所以一开始是在安装 docker 前加的三个链,后面发现还是会出现。今天测试内部环境测试的时候百分之百复现了。

和同事排查了下,确认是部署脚本里没有停止 firewalld ,后面执行 ansible 剧本的时候去停止的。整个流程是:

部署机器 ----安装docker----> ansible 剧本 -----停止firewalld-----> 检测到已经安装 docker 不操作
没运行部署平台的机器 ----> ansible 剧本 -----停止firewalld-----> 安装 docker 并启动 docker daemon

部署机器是先启动 docker daemon,然后后面剧本停止了 firewalld,而非部署机器是先停的 firewalld,再启动的 docker daemon。

手动测试了下发现停止 firewalld 会把 iptables 清空。于是部署脚本里提前把所有系统的 case 逻辑里把 firewalld 给停掉。

另外我们防止有些用户安装了 iptables 的 daemon,是这样停止的。

systemctl stop firewalld python-firewall firewalld-filesystem iptables &>/dev/null
systemctl disable firewalld python-firewall firewalld-filesystem iptables &>/dev/null

发现这样执行后 firewalld 还是 enabled 的状态,如果有不存在的 service (例如机器存在firewalld,后面几个都不存在)则整个 disable 会失效(全部没有 disable 成功)。改成了下面的:

function Systemctl_Stop_Disable(){
for target in $@;
do
sudo systemctl stop $target &>/dev/null || true;
sudo systemctl disable $target &>/dev/null || true;
done
true
}

Systemctl_Stop_Disable firewalld python-firewall firewalld-filesystem iptables

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK