iptables 跳转机制的核心逻辑。让我用一个更直观的方式解释:
一、iptables 跳转的本质:子流程执行后返回原链
当规则中的 -j 链名 指向一个自定义链(如 KUBE-MARK-MASQ)时,iptables 会:
- 跳转到子链:暂停当前链的执行,进入目标链。
- 执行子链规则:按顺序执行目标链中的所有规则。
- 返回原链:子链执行完毕后(或遇到
RETURN指令),回到原链的下一条规则继续执行。
关键点:跳转不是「替换」,而是「暂停-执行-恢复」。
二、用示例说明你的规则如何执行
假设我们有两条规则:
# 规则1:标记数据包以便SNAT
-A KUBE-NODEPORTS -p tcp --dport 30090 -j KUBE-MARK-MASQ# 规则2:转发到服务链
-A KUBE-NODEPORTS -p tcp --dport 30090 -j KUBE-SVC-GFPAJ7EGCNM4QF4H
当一个访问 30090 端口的数据包进入 KUBE-NODEPORTS 链时:
-
匹配规则1:
- 执行
-j KUBE-MARK-MASQ,跳转到KUBE-MARK-MASQ链。 KUBE-MARK-MASQ链内部通常只有一条规则:-A KUBE-MARK-MASQ -j MARK --set-xmark 0x4000/0x4000- 这条规则标记数据包,但不会终止流程(没有
ACCEPT/DROP)。
- 执行
-
返回原链:
KUBE-MARK-MASQ链执行完毕后,回到KUBE-NODEPORTS链的下一条规则(即规则2)。
-
匹配规则2:
- 执行
-j KUBE-SVC-GFPAJ7EGCNM4QF4H,将流量转发到服务链,最终导向后端 Pod。
- 执行
三、为什么需要这种设计?
Kubernetes 通过这种方式实现了两个独立功能的组合:
- 标记 SNAT 需求(规则1):告诉 iptables「这个流量需要做源地址转换」。
- 实际转发流量(规则2):将流量送到正确的目的地。
类比:这就像快递包裹,先贴「加急」标签(规则1),再决定发往哪个仓库(规则2)。两个动作都必须执行。
四、验证执行路径的方法
你可以通过以下方式确认规则的执行逻辑:
-
查看链结构:
iptables -t nat -L -n -v --line-numbers确认
KUBE-MARK-MASQ链中没有ACCEPT/DROP规则,只有MARK操作。 -
统计匹配次数:
iptables -t nat -L KUBE-NODEPORTS -n -v -x如果两条规则的
pkts(包计数)相同,说明它们都被触发了。 -
跟踪单个数据包(调试用):
iptables -t nat -A PREROUTING -p tcp --dport 30090 -j TRACE dmesg | tail # 查看内核日志中的跟踪信息
五、常见误解澄清
误解1:「跳转到一个链后,原链就不会继续执行了」
事实:只有 ACCEPT/DROP/REJECT 会终止流程,普通跳转(如 MARK、DNAT)会返回原链。
误解2:「两条相同匹配条件的规则会冲突」
事实:iptables 会按顺序执行所有匹配的规则,直到遇到终止动作。
总结
你的两条规则之所以都需要,是因为:
- 规则1:标记数据包(非终止动作)。
- 规则2:转发数据包(非终止动作)。
它们共同构成了完整的流量处理路径:标记 → 转发 → 后续 SNAT → 到达后端 Pod。这种设计是 Kubernetes 高效利用 iptables 实现复杂网络功能的关键。
