本质
- Overlay(叠加/隧道)网络技术
- 把 Pod 发出的、物理网络不认识的数据包,在宿主机端套上一层物理网络认识的“外壳”,传送到目的地后再剥掉外壳
IPIP(IP-in-IP)
Note
三层隧道技术(网络层封包)
把一个 IP 报文直接封装在另一个 IP 报文里面
封包结构
当 Pod A(10.244.1.5)访问 Pod B(10.244.2.6)时,数据包在出宿主机前会被套上一层新的 IP 头部:
- 外层 IP 报文头:源 IP = 宿主机 A 的物理 IP,目的 IP = 宿主机 B 的物理 IP,Protocol(协议) 号固定为 4(代表内容是 IPIP 包)。
- 内层 IP 报文头:源 IP = Pod A 的 IP,目的 IP = Pod B 的 IP。
- Payload:实际的业务数据(如 TCP/UDP 内容)。
通信路径
Pod A -> 宿主机 A 路由表 -> tunl0 设备 (执行 IPIP 封包) -> 物理网络三层路由 -> 宿主机 B -> tunl0 设备 (解包) -> Pod B
- 特点:Calico 使用 IPIP 模式时,宿主机上会有一个名为
tunl0的虚拟隧道设备。数据包根据路由表指引进入tunl0,内核自动完成外层 IP 头的剥离或组装。
VXLAN(Virtual Extensible LAN)
Note
四层隧道技术(MAC-in-UDP)
封包结构
VXLAN 封包比 IPIP 要沉重和复杂得多,因为它不仅封装了 IP,还封装了二层以太网的 MAC 地址。它把原始数据包包装成一个宿主机间的 UDP 报文:
- 外层 IP/MAC 头:用于宿主机之间在物理网络中的标准路由与交换。
- 外层 UDP 头:目的端口固定为 4789(VXLAN 官方标准端口)。
- VXLAN 头部:包含一个核心的 VNI(VXLAN Network Identifier,24位),相当于虚拟化网络里的 VLAN ID,用于隔离不同的容器网络。
- 内层 MAC/IP 头:Pod 间通信的原始二层和三层头部。
通信路径
Pod -> 穿过 veth pair 直达宿主机内核 -> 查宿主机路由表 -> 发现下一跳是 `vxlan.calico` 网卡 -> **`vxlan.calico` 直接在内核中原地执行 VXLAN 四层封包** -> 物理网络 UDP 转发 -> 宿主机 B -> 隧道设备 (解包) -> Pod B
- 特点:负责封包和解包的组件叫做 VTEP(VXLAN Tunnel End Point)。在 K8s 中,宿主机上的
flannel.1或vxlan.calico虚拟网卡就是软件实现的 VTEP。
对比
| 对比维度 | IPIP 模式 | VXLAN 模式 |
|---|---|---|
| 封装层级 | 三层封装(直接套 IP 头部) | 四层封装(套在 UDP 报文内) |
| 网络层级 | 纯三层隧道(IP in IP) | 大二层虚拟网络(MAC in UDP) |
| 头部开销 (Overhead) | 20 字节(仅多了一个 IPv4 头) | 50 字节(UDP 8B + VXLAN 8B + 内层MAC 14B + 外层IP 20B) |
| 标准 MTU 推荐值 | 1480(1500 - 20) | 1450(1500 - 50) |
| Linux 内核要求 | 需要加载 ipip 内核模块 | 需要加载 vxlan 内核模块 |
| 物理网络兼容性 | 较低。部分云厂商或严格的物理防火墙会拦截 Protocol 4 的非 TCP/UDP 畸形包。 | 极高。本质是标准 UDP 4789 端口流量,任何交换机、路由器和云厂商都完美放行。 |
| 主流 CNI 支持 | Calico 常用 | Flannel、Calico、Cilium 均支持 |
问题
1. VXLAN 开销大,但云原生时代却更喜欢用
Tip
兼容性
IPIP 封出来的包,其外层 IP 头的协议号是 4,它不属于 TCP(6)、UDP(17)或 ICMP(1)。很多公有云厂商(如 AWS、早期阿里云)的底层 VPC 网络安全策略非常严格,只认识 TCP/UDP,会直接丢弃 IPIP 的流量。
而 VXLAN 聪明在它把大包伪装成了标准的 UDP 4789 端口流量,在任何网络设备看来,它就是一个普通的普通用户流量,能够畅通无阻地穿透各种复杂的云环境和防火墙。
2. MTU 未调整导致的“大文件传输卡死”
- 现象:集群建好后,Pod 之间互相 ping 正常,网页文字加载正常。但是一旦 Pod 之间拉取大镜像、传输几百兆的日志文件、或者执行大数据量的 SQL 查询时,网络就会诡异地卡死、断开或超时(504)。
- 原因:物理网卡的默认 MTU(最大传输单元)是 1500 字节。
- 如果用 VXLAN,由于封装多了 50 字节,实际留给 Pod 的有效空间只有 1450 字节。
- 如果你没有在 CNI 的 YAML 里将 MTU 调小(依然是默认的 1500),Pod 就会发出 1500 字节的满载大包。
- 到了宿主机,VXLAN 加上 50 字节变成了 1550 字节,超过了物理网卡的 1500 限制。此时如果物理网络设备开启了
DF(Don’t Fragment,不允许分片)标志,这个包就会被直接丢弃,导致大文件传输永远过不去。
- 解决方案:在 Calico / Flannel 的配置 YAML 中,显式指定网络 MTU。VXLAN 设为
1450,IPIP 设为1480。