flannel和mss

下面给出一个详细的示意图,描述 Kubernetes 使用 Flannel VXLAN 模式时,数据包如何经过 iptables 各表链(主要是 mangle 表)以及路由决策,同时说明在 POSTROUTING 链上加 TCPMSS 的原因。下面的示意图分为两大部分:

  1. 外部流量或跨节点流量进入容器的过程

  2. 容器发出流量离开节点的过程


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 隧道传输的数据包不会因过大而导致丢包或要求分片。


总结

  1. 流量图涵盖:

    • 外部/跨节点流量从外部服务器进入 Node 1,经过 PREROUTING 处理、路由决策、VXLAN 封装,再通过 POSTROUTING(应用 TCPMSS clamp)出节点,经过物理网络到 Node 2,再经 VXLAN 解封装、PREROUTING、FORWARD 进入容器。

    • 容器发出的数据包从 Docker Bridge出发,通过 FORWARD、POSTROUTING 进行 VXLAN 封装后出节点发送。

  2. iptables 链与路由协同工作:

    • PREROUTING: 进入节点时的初步处理(DNAT、标记、解封装)。

    • FORWARD: 容器与节点之间或跨节点的数据包转发处理。

    • POSTROUTING: 出节点前的最后处理阶段,此处应用 TCPMSS clamp 确保封装后包大小符合物理网络 MTU,避免碎片化和丢包。

    • 路由决策: 根据包目标 IP 由节点路由表决定数据包是否需要跨节点转发以及应用 VXLAN 封装或直连转发。

以上就是一个完整的 Kubernetes Flannel VXLAN 网络中,iptables 各表链及路由的示意图和详细说明,帮助理解数据包如何在各个处理阶段流转,以及为什么在 POSTROUTING 阶段加上 TCPMSS 调整规则的重要性。

posted on 2025-04-16 11:42  吃草的青蛙  阅读(42)  评论(0)    收藏  举报

导航