4. MTU对Cilium的影响:隧道封装开销、VXLAN/Geneve头部、MTU计算模型

在Cilium网络中,MTU(Maximum Transmission Unit,最大传输单元)是决定数据包能否顺利通过物理链路的核心参数。当Cilium启用隧道模式(如VXLAN或Geneve)时,每个原始数据包都会被额外封装一层头部,导致有效载荷空间被压缩。如果主机网络接口的MTU没有为这些封装开销预留余量,就会触发IP分片或丢包,直接影响Pod之间的通信质量。

4.1 隧道封装开销的来源

Cilium默认使用VXLAN或Geneve作为数据平面封装协议。这两种隧道技术都会在原始L2帧之外叠加额外的头部,具体开销如下:

封装层 VXLAN 开销(字节) Geneve 开销(字节) 说明
Outer Ethernet 14 14 外层MAC头部
Outer IP 20 20 外层IPv4头部(无选项)
Outer UDP 8 8 外层UDP头部
VXLAN / Geneve 头部 8 8 + 4×N Geneve支持可变长度选项(N为选项数量)
总开销(无选项) 50 50 基础封装开销
Inner Ethernet 14 14 内部MAC头部(通常被Cilium省略)
关键点:Cilium在隧道模式下默认省略内部Ethernet头部(L2模式),因此实际封装开销通常为 50字节(VXLAN)或 50 + 4×N字节(Geneve)。如果启用了Geneve选项(如元数据传递),开销会进一步增加。

4.2 MTU计算模型

MTU计算的核心原则是:物理接口MTU ≥ 隧道封装开销 + 有效载荷MTU。Cilium在启动时会自动检测主网络接口的MTU,并减去隧道开销,得到Pod接口的MTU。如果手动调整了主机MTU,必须同步更新Cilium的配置。

以下为标准的MTU计算模型:

Pod MTU = Host MTU - Tunnel Overhead

示例(VXLAN,Host MTU = 1500):
Pod MTU = 1500 - 50 = 1450

示例(Geneve,Host MTU = 9000,无选项):
Pod MTU = 9000 - 50 = 8950
常见误区:部分用户误以为Cilium会自动补偿MTU差异。实际上,Cilium仅做减法计算,不会主动修改主机网卡的MTU。如果主机MTU设置不当(例如主机MTU=1500但未减开销),Pod发出的1500字节数据包经过隧道封装后变为1550字节,超出物理链路限制,导致分片或丢弃。

4.3 封装开销对数据包路径的影响

下图展示了VXLAN隧道模式下,一个Pod发出的数据包在穿越Cilium节点时的MTU变化过程:

VXLAN隧道MTU影响路径图 VXLAN隧道模式下MTU变化路径 Pod A MTU = 1450 veth Pair MTU = 1450 Cilium 隧道端点 封装 +50 字节 主机 eth0 MTU = 1500 数据包大小变化示例(Pod发送1450字节有效载荷) ① Pod A 发出:Ethernet(14) + IP(20) + TCP(20) + Payload(1396) = 1450 字节 ② 隧道封装后:OuterEth(14) + OuterIP(20) + UDP(8) + VXLAN(8) + Inner(1450) = 1500 字节 ③ 主机 eth0 发送:1500 字节 → 恰好匹配物理MTU,无需分片 ⚠ 如果Pod MTU未减封装开销(例如Pod MTU=1500): 封装后数据包变为1550字节 → 超出主机eth0的1500 MTU → 触发IP分片或丢包

4.4 不同网络场景下的MTU推荐值

根据底层物理网络和隧道类型,推荐以下MTU配置:

物理网络类型 物理接口MTU 隧道类型 Pod MTU(推荐) 备注
标准以太网(1500) 1500 VXLAN 1450 最常用配置
标准以太网(1500) 1500 Geneve(无选项) 1450 与VXLAN开销相同
标准以太网(1500) 1500 Geneve(4个选项) 1434 额外16字节选项开销
巨型帧(9000) 9000 VXLAN 8950 适合高性能场景
巨型帧(9000) 9000 Geneve(无选项) 8950 推荐用于大包传输
云环境(AWS/GCP/Azure) 9001 / 1460 / 1500 VXLAN 主机MTU - 50 需先确认云厂商底层MTU
云环境特别提示:AWS VPC默认MTU为9001(巨型帧),但部分实例类型或ENI可能限制为1500。GCP的VPC MTU通常为1460(因内部GRE隧道)。Azure标准MTU为1500。务必先通过 ip link show 或云厂商文档确认实际物理MTU,再计算Pod MTU。

4.5 手动调整MTU的方法

如果Cilium自动检测的MTU不符合预期,或需要为特定节点调整MTU,可以通过以下方式手动覆盖:

  1. 全局配置(Helm安装时):
    helm upgrade cilium cilium/cilium \
      --namespace kube-system \
      --reuse-values \
      --set tunnel=vxlan \
      --set mtu=1450
  2. ConfigMap动态调整(运行中集群):
    kubectl edit configmap -n kube-system cilium-config
    # 添加或修改:
    # mtu: "1450"
    # 保存后重启Cilium DaemonSet:
    kubectl rollout restart -n kube-system ds/cilium
  3. 节点级覆盖(通过CiliumNode CRD):
    kubectl edit ciliumnode <node-name>
    # 在 spec 下添加:
    #   mtu: 1450
验证MTU生效:调整后,进入任意Pod执行 ip link show 或 ifconfig,查看eth0接口的MTU值是否与配置一致。也可通过 cilium status 查看集群级别的MTU信息。

4.6 MTU调优的常见陷阱

  • 陷阱1:只调Pod MTU,不调主机MTU。 如果主机eth0的MTU本身小于1500(如某些云环境为1460),即使Pod MTU=1450,封装后仍可能超过主机MTU。必须确保 主机MTU ≥ Pod MTU + 封装开销。
  • 陷阱2:忽略Geneve选项开销。 当Cilium启用高级特性(如节点元数据传递、策略日志)时,Geneve选项可能增加4~20字节开销。建议在测试环境用 tcpdump -i any -s 0 -v 抓包确认实际封装大小。
  • 陷阱3:混合隧道模式与直接路由模式。 如果集群中部分节点使用隧道、部分使用直接路由(如通过 routing-mode=native),MTU配置必须按节点分别计算,不能全局一刀切。
  • 陷阱4:忽略容器网络接口的MTU继承。 某些CNI插件(如Flannel、Calico)会修改Pod的MTU,与Cilium冲突。确保集群中只有一个CNI负责MTU设置,或显式在Cilium配置中锁定MTU值。