flannel和mss
下面给出一个详细的示意图,描述 Kubernetes 使用 Flannel VXLAN 模式时,数据包如何经过 iptables 各表链(主要是 mangle 表)以及路由决策,同时说明在 POSTROUTING 链上加 TCPMSS 的原因。下面的示意图分为两大部分:
-
外部流量或跨节点流量进入容器的过程
-
容器发出流量离开节点的过程
1. 外部/跨节点流量进入容器的示意图
假设一个外部服务器(或来自其他节点的包)要到达目标容器。该流量首先到达源节点(Node 1),经过 VXLAN 封装后通过物理网络传输,再由目标节点(Node 2)接收和解封装后送达容器。示意图如下:
[外部服务器]
│
▼
+---------------------+
| Node 1: 物理接口 | ← 数据包进入 Node 1 (eth0)
| (MTU = 1450/1500) |
+---------------------+
│
┌────────────────────────────────┐
│ iptables PREROUTING (mangle) │ ← 修改包头、DNAT等
└────────────────────────────────┘
│
┌───────────────┐
│ 路由决策 │ ← 根据目标IP判定目的在本节点或跨节点
└───────────────┘
│
┌────────────────────────────┐
│ VXLAN封装(Flannel) │ ← 此处加上额外VXLAN头部(约50字节)
└────────────────────────────┘
│
┌─────────────────────────────┐
│ iptables POSTROUTING (mangle) │ ← 应用 TCPMSS clamp(可选)
└─────────────────────────────┘
│
【物理网络传输】 (经由IP路由, SNAT调整)
│
▼
+---------------------+
| Node 2: 物理接口 | ← 接收封装后的 VXLAN 数据包
| (MTU 与物理网络匹配)|
+---------------------+
│
┌────────────────────────────────┐
│ VXLAN解封装(Flannel.flannel.1)│ ← 将封装包解封为原始包
└────────────────────────────────┘
│
┌───────────────┐
│ iptables PREROUTING (mangle) │ ← 解封后的包进入目标节点处理链
└───────────────┘
│
┌───────────────┐
│ 路由决策 │ ← 查找对应的容器所在网络
└───────────────┘
│
┌─────────────────────────────┐
│ iptables FORWARD (mangle) │ ← 转发、可能附加TCPMSS规则
└─────────────────────────────┘
│
▼
┌─────────────────────┐
│ veth → Docker Bridge│ ← 将包送进目标容器
│ (目标容器) │
└─────────────────────┘
分析说明
-
PREROUTING(mangle):
当数据包进入 Node 1 和 Node 2 时,会先进入 PREROUTING 链进行初步处理(例如打标记、DNAT)。 -
路由决策:
根据目标 IP 地址,决定数据包是在当前节点终结,还是需要跨节点传输。 -
VXLAN封装/解封装:
在 Node 1,数据包经过 VXLAN 封装后加上 50 字节左右的头部,降低实际有效 MTU;Node 2 则解封装,还原原始数据包。 -
POSTROUTING(mangle):
在封装前,通常会在 POSTROUTING 链上使用 TCPMSS 规则(--clamp-mss-to-pmtu)调整 MSS,保证经过 VXLAN 封装后的包不会超过物理网络 MTU,避免丢包。 -
FORWARD(mangle):
处理跨节点和容器之间转发的流量,将包从物理或虚拟接口传递到容器。
2. 容器发出流量离开节点的示意图
当容器发送数据包(例如访问外部资源或跨节点访问其他容器)时,流量从容器出发,通过 Docker bridge、veth 接口进入宿主机,再经过 iptables 处理和 VXLAN 封装后出节点传输。示意图如下:
┌─────────────────────┐
│ Container (Pod) │
│ (IP: 10.244.x.x) │
└─────────────────────┘
│
▼
[veth → Docker Bridge]
│
▼
┌───────────────────────────┐
│ iptables FORWARD (mangle) │ ← 本地转发处理(容器 → Node)
└───────────────────────────┘
│
┌───────────────┐
│ 路由决策 │ ← 判断目的地址:外部/跨节点?
└───────────────┘
│
┌─────────────────────────────┐
│ iptables POSTROUTING (mangle)│ ← 应用 TCPMSS clamp,确保包大小合适
└─────────────────────────────┘
│
┌────────────────────────────┐
│ VXLAN封装(Flannel) │ ← 加入VXLAN头部进行跨节点传输
└────────────────────────────┘
│
▼
【物理网络传输】
分析说明
-
FORWARD(mangle):
容器发出的数据包从 Docker bridge 进入宿主机后,会进入 FORWARD 链进行转发。 -
POSTROUTING(mangle):
在数据包离开节点前,通过 POSTROUTING 链应用 TCPMSS clamp 规则,动态调整 TCP MSS,使得在 VXLAN 封装后数据包大小符合物理网络 MTU 限制。 -
VXLAN封装:
在 POSTROUTING 后,对流量进行VXLAN封装,加上额外头部后进行跨节点传输。
为什么在 POSTROUTING 链上加 TCPMSS(--clamp-mss-to-pmtu)
-
最终出站前调整:
数据包经过路由决定、转发、封装之后,最终从节点的物理接口发出,此时最适合在 POSTROUTING 阶段调整 MSS。 -
防止超出 MTU:
VXLAN 封装会添加大约 50 字节头部,原始 TCP 数据包如果没有调整,封装后可能超出物理网络 MTU而导致数据包被丢弃或要求分片。 -
动态适应路径 MTU:
使用--clamp-mss-to-pmtu选项会自动根据路径的最大传输单元(PMTU)调整 MSS 值,确保各段网络都能正常传输数据包而不触发碎片化。
命令示例:
iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
这条规则的工作原理是:
-
对所有 TCP 握手(SYN)包进行检查和修改。
-
动态计算当前路径的 MTU(考虑到了物理网络、VXLAN封装带来的变化),并将 TCP 数据包的 MSS 限制为合适的大小(一般为 PMTU - 40 字节左右)。
-
从而保证跨节点、通过 VXLAN 隧道传输的数据包不会因过大而导致丢包或要求分片。
总结
-
流量图涵盖:
-
外部/跨节点流量从外部服务器进入 Node 1,经过 PREROUTING 处理、路由决策、VXLAN 封装,再通过 POSTROUTING(应用 TCPMSS clamp)出节点,经过物理网络到 Node 2,再经 VXLAN 解封装、PREROUTING、FORWARD 进入容器。
-
容器发出的数据包从 Docker Bridge出发,通过 FORWARD、POSTROUTING 进行 VXLAN 封装后出节点发送。
-
-
iptables 链与路由协同工作:
-
PREROUTING: 进入节点时的初步处理(DNAT、标记、解封装)。
-
FORWARD: 容器与节点之间或跨节点的数据包转发处理。
-
POSTROUTING: 出节点前的最后处理阶段,此处应用 TCPMSS clamp 确保封装后包大小符合物理网络 MTU,避免碎片化和丢包。
-
路由决策: 根据包目标 IP 由节点路由表决定数据包是否需要跨节点转发以及应用 VXLAN 封装或直连转发。
-
以上就是一个完整的 Kubernetes Flannel VXLAN 网络中,iptables 各表链及路由的示意图和详细说明,帮助理解数据包如何在各个处理阶段流转,以及为什么在 POSTROUTING 阶段加上 TCPMSS 调整规则的重要性。
浙公网安备 33010602011771号