问题背景
K8S集群环境中有个容器化的组件A需要在节点上创建iptables规则实现请求转换,在centos 7的操作系统上功能正常,但在redhat 8的操作系统上发现该功能失效。具体来说,就是容器内iptables命令执行后没有生效。
分析过程
业务组件A的功能是基于iptables命令的,查看当前容器内使用的iptables版本:
1 | ~ # iptables -V |
查看使用的centos 7宿主机上的iptables版本:
1 | [root@node1 ~]# iptables -V |
对比redhat8.4的环境,发现它提供的iptables版本较高,且**模式从默认的legacy变成了nf_tables**:
1 | [root@node1 ~]# iptables -V |
从redhat官方资料看[1],该模式无法修改,因为在制作rpm包时删掉了legacy模式依赖的二进制文件:
1 | iptables changelog: |
而其他操作系统,如debian、alpine安装的高版本iptables均支持legacy和nf_tables两种模式,且支持切换:
1 | update-alternatives --set iptables /usr/sbin/iptables-legacy |
至此,基本确认是iptables模式不匹配导致的规则下发失效。实测在redhat8.4的环境,基于alpine的基础镜像制作的组件A,通过上述命令修改iptables为nf_tables模式后,规则下发正常。
解决方案
为了同时支持centos 7和redhat 8,组件A需要在容器启动时按需选择iptables的模式,保证老环境使用原来的legacy模式,新环境调整为nf_tables模式。