iptables 版本查看
在 Kubernetes 集群中,kube-proxy 是实际使用 iptables(或 IPVS)来实现 Service 转发的核心组件。要判断当前集群默认使用的是 iptables-legacy 还是 iptables-nft(nftables 后端),需从 节点操作系统层面 判断,因为 kube-proxy 本身不直接指定“legacy”或“nft”,而是调用系统默认的 iptables 命令。
以下是几种准确的排查方法:
✅ 方法一:查看系统默认的 iptables 后端(推荐)
在任意 Node 节点(尤其是出问题的 26 网段节点)上执行:
# 查看 iptables 实际指向哪个版本
ls -l /usr/sbin/iptables
# 或者使用 update-alternatives(适用于 Debian/Ubuntu/CentOS 7+)
sudo update-alternatives --display iptables
输出示例分析:
-
如果指向
iptables-legacy:bash编辑/usr/sbin/iptables -> /usr/sbin/xtables-legacy-multi # 或 link currently points to /usr/sbin/iptables-legacy→ 表示使用 legacy 模式
-
如果指向
iptables-nft:bash编辑/usr/sbin/iptables -> /usr/sbin/xtables-nft-multi # 或 link currently points to /usr/sbin/iptables-nft→ 表示使用 nftables 后端(即 iptables-nft)
💡 注意:CentOS/RHEL 8+ 和 Ubuntu 20.04+ 默认使用
iptables-nft。
✅ 方法二:通过内核模块和规则表类型判断
运行以下命令:
# 查看是否加载了 nftables 相关模块
lsmod | grep nft
# 查看当前活跃的 nft 规则(如果有输出,说明系统在用 nft)
nft list ruleset
# 同时检查 iptables-legacy 是否还能列出 kube-proxy 规则
iptables-legacy-save | grep KUBE-SERVICES
iptables-nft-save | grep KUBE-SERVICES
- 如果
iptables-nft-save能看到 KUBE 规则,而iptables-legacy-save看不到 → 当前使用 nft - 反之则为 legacy
✅ 方法三:查看 kube-proxy 日志(间接判断)
虽然 kube-proxy 不显式打印“使用 legacy/nft”,但可通过其调用行为推断:
kubectl logs -n kube-system <kube-proxy-pod-name> | grep -i "Using.*backend"
不过通常不会直接显示。更有效的是结合方法一。
✅ 方法四:检查 kube-proxy 启动参数(确认是否强制指定)
查看 kube-proxy 的 ConfigMap 或 DaemonSet:
kubectl get configmap -n kube-system kube-proxy -o yaml | grep -A5 -B5 iptables
如果看到类似:
mode: "iptables"
这只是表示使用 iptables 模式(而非 IPVS),不区分 legacy/nft。真正的后端由操作系统决定。
🔍 快速一键判断脚本(在节点上运行)
#!/bin/bash
echo "=== iptables 后端检测 ==="
if command -v update-alternatives &> /dev/null; then
echo "update-alternatives 设置:"
sudo update-alternatives --display iptables 2>/dev/null | grep "link currently points to"
fi
echo "iptables 二进制指向:"
ls -l /usr/sbin/iptables
echo "尝试列出 KUBE 规则(legacy vs nft):"
echo "[legacy] 条数: $(iptables-legacy-save 2>/dev/null | grep -c KUBE || echo 0)"
echo "[nft] 条数: $(iptables-nft-save 2>/dev/null | grep -c KUBE || echo 0)"
运行后即可明确当前生效的是哪一套。
📌 总结
| 判断方式 | 关键命令 | 结果含义 |
|---|---|---|
| 软链接/alternatives | ls -l /usr/sbin/iptables |
指向 -legacy 或 -nft |
| 规则存在性 | iptables-legacy-save | grep KUBE vs nft |
哪个有规则,哪个就是当前后端 |
| 系统发行版默认 | CentOS 8+/Ubuntu 20.04+ 默认为 nft | 需特别注意 |
⚠️ 特别提醒
Kubernetes 官方建议:集群内所有节点必须使用相同的 iptables 后端。混合使用 legacy 和 nft 会导致规则不一致、连接跟踪异常、UDP 丢包等问题——这正是你遇到的 CoreDNS 解析失败的根本原因。
✅ 解决方案:统一所有节点为 iptables-legacy(兼容性最好),或全部升级到 nft 并确保内核和 kube-proxy 版本兼容。
如需我提供统一切换为 legacy 的批量操作脚本,也可以告诉我。
你看到的这个软链接:
lrwxrwxrwx. 1 root root 13 10月 15 2021 /usr/sbin/iptables -> xtables-multi
说明你的系统使用的是 较老版本的 iptables 工具链,尚未启用 legacy / nft 的多后端机制。
🔍 这个 xtables-multi 是什么?
xtables-multi是 传统 iptables 工具(即“legacy”模式)的统一二进制文件。- 它是一个 多合一程序(multi-call binary),根据调用时的命令名(如
iptables、ip6tables、arptables等)执行不同功能。 - 这种形式常见于 CentOS 7 / RHEL 7 / Ubuntu 18.04 及更早版本,这些系统默认只支持 legacy 模式,还没有引入基于 nftables 的
iptables-nft后端。
✅ 所以:
/usr/sbin/iptables -> xtables-multi表示你当前使用的是iptables-legacy(传统模式)。
🆚 对比现代系统的结构(如 CentOS 8+ / Ubuntu 20.04+)
在新系统中,你会看到:
/usr/sbin/iptables -> /etc/alternatives/iptables
/etc/alternatives/iptables -> /usr/sbin/iptables-nft # 或 iptables-legacy
并且存在两个独立的二进制文件:
/usr/sbin/iptables-legacy/usr/sbin/iptables-nft
而你的系统只有 xtables-multi,说明:
- 内核可能较旧(< 4.19)
- 或发行版未启用 nftables 作为 iptables 后端
- 无论如何,当前行为等同于
iptables-legacy
✅ 如何进一步确认?
你可以运行以下命令验证是否真的在用 legacy 模式:
# 查看内核是否加载了 nf_tables(nftables 核心模块)
lsmod | grep nf_tables
- 如果 没有输出 → 很可能没启用 nftables,iptables 走的是纯 legacy 路径。
- 如果有输出,但
iptables仍指向xtables-multi,说明虽然内核支持 nftables,但用户态工具仍在用 legacy。
再检查规则表类型:
# 查看 iptables 规则是否由 legacy 引擎管理
cat /proc/net/ip_tables_names
- 如果有输出(如
nat,filter等)→ 说明 legacy iptables 正在使用 - 而 nftables 的规则不会出现在这里,而是通过
nft list ruleset查看
📌 结论
/usr/sbin/iptables -> xtables-multi= 使用 iptables-legacy(传统模式)
这意味着:
- 你的节点 不是 因为“混用 legacy/nft”导致问题;
- 但你之前提到 master 和 node 内核版本不一致,仍可能导致 conntrack 行为差异 或 iptables 内核模块兼容性问题(即使都是 legacy);
- 特别是:高版本内核(如 5.x)对 UDP conntrack 的处理更严格,可能导致短连接 DNS 请求被提前丢弃。
🔧 建议下一步排查
既然确认是 legacy 模式,但仍有 UDP DNS 解析失败,可检查:
1. conntrack 表是否溢出?
dmesg | grep -i "table full"
cat /proc/sys/net/netfilter/nf_conntrack_max
cat /proc/sys/net/netfilter/nf_conntrack_count
2. 调整 UDP 超时时间(临时缓解)
# 默认 udp timeout 可能太短(如 30s),DNS 查询若延迟可能被清理
echo 60 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout
echo 120 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream
3. 抓包确认 UDP 包是否到达 CoreDNS Pod
在 26 网段 node 上:
# 抓 Service IP 的 UDP 53(应看到请求,但无响应)
tcpdump -i any host <coredns-service-ip> and port 53
# 抓 CoreDNS Pod IP 的 UDP 53(应看不到请求 → 说明 DNAT 失败)
tcpdump -i any host <coredns-pod-ip> and port 53
如果前者有包、后者无包 → iptables DNAT 规则未生效或 conntrack 异常
如需进一步分析,可以提供:
uname -r(内核版本)iptables-save | grep KUBE-SVC-<coredns-hash>cat /etc/os-release
我可以帮你判断是否是内核 conntrack 行为变更导致的问题。
浙公网安备 33010602011771号