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变化过程:
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,可以通过以下方式手动覆盖:
- 全局配置(Helm安装时):
helm upgrade cilium cilium/cilium \ --namespace kube-system \ --reuse-values \ --set tunnel=vxlan \ --set mtu=1450 - ConfigMap动态调整(运行中集群):
kubectl edit configmap -n kube-system cilium-config # 添加或修改: # mtu: "1450" # 保存后重启Cilium DaemonSet: kubectl rollout restart -n kube-system ds/cilium - 节点级覆盖(通过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值。