4. 容器网络基础:Overlay网络(VXLAN)原理与数据封装解封装过程

在容器化环境中,Pod 或容器通常被分配一个仅在宿主机内部可达的 IP 地址(如 Flannel 的 host-gw 模式或 Calico 的纯路由模式)。当容器需要跨宿主机通信时,底层网络(Underlay)往往无法直接路由这些容器 IP。Overlay 网络通过在宿主机之间建立“隧道”,将容器数据包封装在宿主机可路由的报文中,从而解决跨主机容器通信问题。VXLAN(Virtual Extensible LAN)是目前最主流的 Overlay 隧道协议之一。

4.1 VXLAN 核心概念与术语

VXLAN 是一种 MAC-in-UDP 的封装技术,它将二层以太网帧封装在 UDP 数据报文中,通过三层 IP 网络传输。理解以下核心术语是掌握 VXLAN 的基础:

术语 缩写 说明
VXLAN 网络标识符 VNI 24 位标识符,用于区分不同的 Overlay 二层网络,支持多达 16M 个隔离网络。
VTEP VXLAN Tunnel Endpoint VXLAN 隧道的端点,负责封装和解封装。通常运行在宿主机内核或 OVS 中。
Underlay 网络 — 物理底层网络,通常是三层 IP 网络,负责传输封装后的 UDP 报文。
Overlay 网络 — 构建在 Underlay 之上的虚拟二层网络,容器直接感知不到底层物理拓扑。
VXLAN 头部 VXLAN Header 8 字节,包含 VNI 和标志位,紧跟在 UDP 头部之后。
关键区别:VNI 类似于传统 VLAN 的 802.1Q Tag,但 VLAN ID 只有 12 位(4096 个),而 VNI 有 24 位(约 1600 万个),极大地扩展了多租户网络的隔离能力。

4.2 VXLAN 数据封装过程(出方向)

当宿主机 A 上的容器需要向宿主机 B 上的容器发送数据时,VTEP 会执行以下封装步骤:

  1. 原始数据包:容器 A 发出标准的以太网帧,目标 MAC 为容器 B 的 MAC 地址,目标 IP 为容器 B 的 IP。
  2. VXLAN 头部封装:VTEP 将原始以太网帧作为 Payload,在其前面添加 8 字节的 VXLAN 头部,其中填入目标 VNI。
  3. UDP 头部封装:在 VXLAN 头部前添加 UDP 头部。源端口通常由哈希计算得出(用于负载均衡),目标端口固定为 4789(IANA 分配)。
  4. 外层 IP 头部封装:在 UDP 头部前添加外层 IP 头部。源 IP 为宿主机 A 的物理 IP,目标 IP 为宿主机 B 的物理 IP。
  5. 外层 MAC 头部封装:最后添加外层以太网帧头部,源 MAC 为宿主机 A 的物理网卡 MAC,目标 MAC 为下一跳路由器或宿主机 B 的物理网卡 MAC。
封装后的报文结构(从内到外):
[原始容器以太网帧] → [VXLAN Header (8B)] → [UDP Header (8B)] → [外层 IP Header (20B)] → [外层 MAC Header (14B)]

4.3 VXLAN 数据解封装过程(入方向)

宿主机 B 的 VTEP 收到封装后的 UDP 报文后,执行逆过程:

  1. 外层 MAC 校验与剥离:检查外层 MAC 地址是否匹配,匹配后剥离外层以太网帧头部。
  2. 外层 IP 校验与剥离:检查外层 IP 目标地址是否为本地物理 IP,匹配后剥离外层 IP 头部。
  3. UDP 校验与剥离:检查 UDP 目标端口是否为 4789,匹配后剥离 UDP 头部。
  4. VXLAN 头部解析:读取 VNI,确认该报文属于哪个 Overlay 网络。如果本地没有对应 VNI 的 VTEP 接口,则丢弃。
  5. 原始帧转发:将剥离出的原始以太网帧根据目标 MAC 地址,通过对应的 Overlay 网桥或路由转发给目标容器 B。
性能陷阱:VXLAN 的封装和解封装过程涉及多次内存拷贝和 CPU 计算(如 UDP 校验和、外层 IP 校验和)。在容器高并发 IO 场景下,频繁的封装/解封装会成为 CPU 瓶颈,导致网络吞吐量下降和延迟增加。这是后续章节“性能优化”的重点关注对象。

4.4 VXLAN 封装结构示意图

下图展示了从容器原始数据包到最终在物理网络上传输的完整封装层次:

VXLAN 数据封装层次结构 原始容器以太网帧(目标 MAC + 目标 IP + Payload) VXLAN Header(8 Bytes)— VNI = 10001 UDP Header(8 Bytes)— 源端口: 哈希值 | 目标端口: 4789 外层 IP Header(20 Bytes)— 源IP: 宿主机A | 目标IP: 宿主机B 外层 MAC Header(14 Bytes)— 源MAC: 宿主机A物理网卡 | 目标MAC: 下一跳/宿主机B 物理网络传输的是封装后的 UDP 报文,容器原始帧完全不可见

4.5 VXLAN 跨宿主机通信流程

下图展示了两个宿主机上的容器通过 VXLAN 隧道进行通信的完整数据流:

VXLAN 跨宿主机容器通信流程 宿主机 A(VTEP A) 容器 A IP: 10.1.1.2 VTEP A 物理IP: 192.168.1.10 封装过程 原始帧 → VXLAN头 → UDP头 → 外层IP头 → 外层MAC头 物理网络 宿主机 B(VTEP B) VTEP B 物理IP: 192.168.1.20 容器 B IP: 10.1.1.3 解封装过程 外层MAC头 → 外层IP头 → UDP头 → VXLAN头 → 原始帧 关键路径:容器A → VTEP A(封装)→ 物理网络 → VTEP B(解封装)→ 容器B 整个过程中,容器A和容器B感知不到物理网络的存在,认为彼此在同一个二层广播域内

4.6 VXLAN 与容器网络的结合

在 Kubernetes 或容器编排平台中,VXLAN 通常由 CNI 插件(如 Flannel VXLAN 模式、Calico VXLAN 模式、Weave Net)实现。容器进程的网络 IO 路径如下:

  • 容器内发包:容器进程通过 veth pair 将数据包发送到宿主机根网络命名空间中的 cni0/docker0 网桥。
  • 路由决策:宿主机内核根据目标容器 IP 查找路由表,发现目标不在本地,需要经过 flannel.1(VXLAN VTEP 接口)转发。
  • VTEP 封装:flannel.1 接口执行 VXLAN 封装,将原始帧封装为 UDP 报文,通过物理网卡 eth0 发送出去。
  • 对端接收:对端宿主机 eth0 收到报文,flannel.1 接口解封装,恢复原始帧,通过 cni0 网桥转发给目标容器。
性能关键点:整个 IO 路径中,VXLAN 封装/解封装发生在内核态(或 OVS 用户态),涉及两次额外的数据拷贝(原始帧 → 封装缓冲区 → 物理网卡发送缓冲区)。每次拷贝都会消耗 CPU 周期和内存带宽,是容器网络 IO 容量的主要瓶颈之一。

4.7 常见问题与避坑指南

问题 原因 影响
MTU 问题导致丢包 VXLAN 封装增加 50 字节头部(VXLAN 8B + UDP 8B + IP 20B + MAC 14B),若物理网络 MTU 未调整,容器内大包会被分片或丢弃。 容器间 TCP 连接不稳定,吞吐量下降。
UDP 校验和卸载未开启 VXLAN 使用 UDP 封装,若网卡不支持 TSO/GRO 或校验和卸载,CPU 需要计算校验和,增加开销。 CPU 占用率升高,小包场景性能下降明显。
ARP 表/转发表膨胀 大规模集群中,每个 VTEP 需要维护所有远端容器 MAC 和 VNI 的映射关系,表项过多导致查询延迟。 首次通信延迟增加,控制平面压力大。
多路复用不足 VXLAN 源端口基于哈希计算,若哈希冲突严重,可能导致物理链路负载不均。 部分链路拥塞,整体吞吐量受限。