由来
我们内部有套部署的工具, 我们部署的流程是先在部署机器(部署机器可能也是node1 )上用脚本安装好 docker,然后进容器里去起我们部署平台,有个很久的 bug 就是,部署机器上端口映射起容器会有如下报错
1 | 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 |
排查也很简单,缺少链,添加上即可:
1 | sudo iptables --wait -N DOCKER &>/dev/null || true |
或者重启 docker daemon 会在启动的时候加上链。脚本安装 docker 的时候,我们执行了下面的
1 | sudo iptables --wait -P INPUT ACCEPT && \ |
所以一开始是在安装 docker 前加的三个链,后面发现还是会出现。今天测试内部环境测试的时候百分之百复现了。
引起原因
和同事排查了下,确认是部署脚本里没有停止 firewalld ,后面执行 ansible 剧本的时候去停止的。整个流程是:
1 | 部署机器 ----安装docker----> ansible 剧本 -----停止firewalld-----> 检测到已经安装 docker 不操作 |
部署机器是先启动 docker daemon,然后后面剧本停止了 firewalld,而非部署机器是先停的 firewalld,再启动的 docker daemon。
手动测试了下发现停止 firewalld 会把 iptables 清空。于是部署脚本里提前把所有系统的 case 逻辑里把 firewalld 给停掉。
另外我们防止有些用户安装了 iptables 的 daemon,是这样停止的。
1 | systemctl stop firewalld python-firewall firewalld-filesystem iptables &>/dev/null |
发现这样执行后 firewalld 还是 enabled 的状态,如果有不存在的 service (例如机器存在firewalld,后面几个都不存在)则整个 disable 会失效(全部没有 disable 成功)。改成了下面的:
1 | function Systemctl_Stop_Disable(){ |