1. 问题现象与背景分析
最近在维护Kubernetes集群时遇到一个典型问题:服务器重启后,部分Pod网络连接异常,跨节点通信失效。检查发现是iptables规则丢失导致,特别是FORWARD链的关键规则不见了。这种情况在刚接触K8s网络的新手中相当常见,但背后涉及Linux网络栈和K8s网络插件的协同工作机制。
Kubernetes网络模型要求所有Pod能够直接通信,这依赖于底层网络插件(如Flannel、Calico等)配置的iptables规则。当节点重启后,如果这些规则没有持久化保存,就会导致:
- 跨节点Pod通信中断(FORWARD链规则丢失)
- Service流量转发异常(nat表规则丢失)
- DNS解析失败(相关链规则缺失)
关键点:iptables规则默认存储在内存中,重启后不会自动保留。这与firewalld等有持久化机制的工具不同。
2. iptables规则管理机制解析
2.1 iptables规则生命周期
理解规则丢失问题,需要先掌握iptables的工作机制:
- 运行时规则:通过
iptables命令直接修改的规则立即生效,但仅保存在内存中 - 持久化规则:需要手动保存到
/etc/sysconfig/iptables(CentOS/RHEL)或/etc/iptables/rules.v4(Debian/Ubuntu) - 恢复机制:系统启动时通过iptables服务加载保存的规则
常见发行版的差异:
| 发行版 | 配置文件位置 | 保存命令 | 恢复服务 |
|---|---|---|---|
| CentOS/RHEL | /etc/sysconfig/iptables | service iptables save | iptables服务 |
| Debian/Ubuntu | /etc/iptables/rules.v4 | iptables-save > 文件 | netfilter-persistent |
| Kylin | /etc/iptables/rules.v4 | iptables-save > 文件 | 需手动配置 |
2.2 Kubernetes网络插件与iptables的交互
以Flannel为例,其网络流程涉及的关键iptables规则:
FORWARD链:允许Pod流量跨节点转发
-A FORWARD -s 10.244.0.0/16 -j ACCEPT -A FORWARD -d 10.244.0.0/16 -j ACCEPTnat表:实现Service的IPVS和DNS转发
-A POSTROUTING -s 10.244.0.0/16 ! -d 224.0.0.0/4 -j MASQUERADE
这些规则通常由网络插件在初始化时动态生成,但不会自动持久化。
3. 完整解决方案与实施步骤
3.1 临时恢复网络
当发现规则丢失时,可立即执行:
# 重启网络插件(以Flannel为例) systemctl restart flanneld # 或重启kube-proxy kubectl -n kube-system delete pod -l k8s-app=kube-proxy3.2 持久化iptables规则
方法一:使用系统工具保存(推荐)
CentOS/RHEL系列:
# 安装iptables服务 yum install iptables-services -y # 保存当前规则 service iptables save # 启用开机加载 systemctl enable iptablesDebian/Ubuntu系列:
# 安装持久化工具 apt install iptables-persistent -y # 保存规则(会提示保存IPv4规则) netfilter-persistent save方法二:手动保存与恢复
# 保存规则 iptables-save > /etc/iptables/rules.v4 # 创建systemd服务(适用于所有发行版) cat > /etc/systemd/system/iptables-restore.service <<EOF [Unit] Description=Restore iptables rules After=network.target [Service] Type=oneshot ExecStart=/sbin/iptables-restore < /etc/iptables/rules.v4 [Install] WantedBy=multi-user.target EOF # 启用服务 systemctl enable iptables-restore3.3 Kubernetes特定优化配置
对于生产环境,建议:
配置kubelet参数:
--iptables-sync-period=30s # 规则同步间隔 --iptables-min-sync-period=10s使用网络插件持久化功能: Calico等插件支持自动规则持久化,在配置中添加:
ipip: enabled: true iptablesBackend: NFT # 或legacy
4. 深度排查与疑难解答
4.1 诊断流程图
Pod网络异常 | v 检查节点基础网络 | v 确认iptables规则存在性 |-- 存在 -> 检查规则顺序 |-- 不存在 -> 检查持久化配置 | v 验证网络插件状态 | v 检查内核参数(net.ipv4.ip_forward等)4.2 常见错误案例
案例1:规则被覆盖
# 错误操作:直接重定向保存 iptables-save > /etc/sysconfig/iptables # 正确做法:使用工具保存 service iptables save案例2:加载顺序问题
# 网络插件启动前加载了空规则 # 解决方案:调整服务启动顺序 systemctl edit flanneld [Unit] After=iptables-restore.service案例3:麒麟系统特殊处理
# 麒麟V10需要额外步骤 mkdir -p /etc/iptables && iptables-save > /etc/iptables/rules.v4 cp /usr/lib/systemd/system/netfilter-persistent.service /etc/systemd/system/ systemctl enable netfilter-persistent5. 高级防护与自动化方案
5.1 监控iptables规则变化
# 使用inotifywait监控规则文件 apt install inotify-tools -y inotifywait -m /etc/iptables/rules.v4 -e modify | while read path action file; do echo "规则文件被修改,正在重新加载..." iptables-restore < /etc/iptables/rules.v4 done5.2 使用Ansible批量修复
- name: Ensure iptables persistence hosts: k8s_nodes tasks: - name: Save current rules shell: iptables-save > /etc/iptables/rules.v4 when: ansible_os_family == 'Debian' - name: Enable restore service template: src: iptables-restore.service.j2 dest: /etc/systemd/system/iptables-restore.service notify: reload systemd handlers: - name: reload systemd systemd: daemon_reload: yes5.3 内核参数优化
# /etc/sysctl.conf 关键配置 net.ipv4.ip_forward=1 net.bridge.bridge-nf-call-iptables=1 net.bridge.bridge-nf-call-ip6tables=1应用配置:
sysctl -p6. 架构层面的思考
在生产环境中,仅解决iptables持久化是不够的。建议:
网络插件选型:
- Calico:内置规则持久化机制
- Cilium:使用eBPF减少对iptables依赖
节点初始化标准化:
# 在节点初始化脚本中加入 apt install iptables-persistent -y iptables-save > /etc/iptables/rules.v4混沌工程测试:
# 定期模拟重启测试 kubectl drain <node> --delete-emptydir-data --force --ignore-daemonsets reboot
我在多个集群的维护中发现,90%的K8s网络问题都与iptables规则管理不当有关。特别是在使用国产化操作系统(如麒麟)时,需要特别注意服务管理方式的差异。建议将iptables持久化检查纳入集群巡检清单,这能预防大量潜在故障。