3. 容器网络数据平面:CNI插件、Overlay网络(VXLAN/Geneve)、Pod网络命名空间、veth pair原理
容器网络数据平面是Pod间通信的物理与逻辑通道。理解CNI插件如何编排网络资源、Overlay封装如何跨宿主机传输数据、网络命名空间如何隔离Pod、veth pair如何连接容器与宿主机,是定位XDP日志中丢包、延迟、校验和错误等异常的根本前提。
3.1 CNI插件:网络配置的编排者
容器网络接口(CNI)是Kubernetes与网络实现之间的标准协议。CNI插件负责在Pod创建时分配网络资源,在Pod销毁时回收资源。其核心工作流程如下:
- ADD操作:kubelet调用CNI插件二进制,传入容器ID、网络命名空间路径、网络配置JSON。
- 分配IP:插件通过IPAM(如host-local、calico-ipam)从指定CIDR中分配IP地址。
- 创建veth pair:将一对veth的一端放入Pod网络命名空间,另一端留在宿主机根命名空间。
- 配置路由与ARP:在宿主机和Pod内分别添加路由表项,确保流量可达。
- 连接Overlay或Underlay:根据网络模式,将宿主机端veth桥接到Overlay隧道或直接路由。
| CNI插件 | 数据平面类型 | 封装协议 | 典型场景 |
|---|---|---|---|
| Calico | 纯路由(BGP)或Overlay | IPIP / VXLAN | 大规模集群,策略丰富 |
| Flannel | Overlay | VXLAN / host-gw | 快速部署,简单网络 |
| Cilium | eBPF原生路由 / Overlay | VXLAN / Geneve | 高性能,可观测性 |
| Weave | Overlay | Weave Mesh(UDP封装) | 跨云混合部署 |
XDP运维提示: CNI插件在ADD阶段创建的veth pair和路由规则,会直接影响XDP程序挂载点的可见性。若XDP程序挂载在宿主机侧veth,则只能看到从Pod发出的原始报文(未封装);若挂载在隧道设备上,则看到的是封装后的Overlay报文。日志关联时必须明确当前XDP探测点位于哪个网络层。
3.2 Overlay网络:VXLAN与Geneve封装
Overlay网络通过在原始报文外增加外层UDP/IP头,实现跨宿主机Pod通信。VXLAN和Geneve是当前最主流的Overlay协议。
3.2.1 VXLAN封装结构
VXLAN将二层以太网帧封装在UDP数据报中,使用24位VNI(VXLAN Network Identifier)标识租户网络。标准端口为4789。
+-------------------------------+
| 外层MAC头 (14B) |
+-------------------------------+
| 外层IP头 (20B) |
+-------------------------------+
| 外层UDP头 (8B) dst_port=4789 |
+-------------------------------+
| VXLAN头 (8B) |
| Flags(1B) | Reserved(3B) |
| VNI(3B) | Reserved(1B) |
+-------------------------------+
| 内层以太网帧 (14B + Payload) |
+-------------------------------+
| FCS (4B) |
+-------------------------------+
3.2.2 Geneve封装结构
Geneve是VXLAN的演进版本,支持可变长度选项头(TLV),提供更灵活的元数据传递能力。标准端口为6081。
+-------------------------------+
| 外层MAC头 (14B) |
+-------------------------------+
| 外层IP头 (20B) |
+-------------------------------+
| 外层UDP头 (8B) dst_port=6081 |
+-------------------------------+
| Geneve头 (8B) |
| Ver(2b) | OptLen(6b) |
| OAM(1b) | Crit(1b) | Rsvd(6b)|
| Protocol Type(16b) |
| VNI(24b) | Rsvd(8b) |
+-------------------------------+
| 选项头 (可变长度, 4B对齐) |
+-------------------------------+
| 内层报文 (IP或以太网) |
+-------------------------------+
| FCS (4B) |
+-------------------------------+
| 特性 | VXLAN | Geneve |
|---|---|---|
| 标准 | RFC 7348 | RFC 8926 |
| VNI长度 | 24位 | 24位 |
| 选项头 | 不支持 | 支持可变长度TLV |
| UDP端口 | 4789 | 6081 |
| MTU开销 | 50字节 | 50字节 + 选项长度 |
| 主要使用者 | Flannel, Calico, OVS | Cilium, OVN-Kubernetes |
XDP日志关联关键点: 当XDP程序在宿主机物理网卡或隧道设备上捕获报文时,看到的将是封装后的外层头。若XDP日志中源IP为宿主机节点IP而非Pod IP,说明报文处于封装态。根因定位时,需要根据外层UDP端口(4789/6081)判断Overlay类型,并解封装后提取内层五元组进行关联。
3.3 Pod网络命名空间与veth pair原理
每个Pod拥有独立的网络命名空间(netns),提供隔离的网络栈:独立的网卡、路由表、ARP表、iptables规则。veth pair是一对虚拟以太网设备,像一根双向管道,一端在Pod netns内,另一端在宿主机根netns中。
3.3.1 网络命名空间隔离边界
- 网卡设备:Pod内只能看到自己的eth0(veth pair的一端),看不到宿主机eth0或其他Pod的网卡。
- 路由表:Pod内默认路由指向宿主机侧veth或网关,宿主机路由表负责跨节点转发。
- ARP表:Pod内ARP表仅包含网关和同子网邻居,宿主机ARP表包含所有节点。
- iptables/nftables:Pod内规则集独立,宿主机规则影响所有Pod的宿主机侧流量。
3.3.2 veth pair数据流原理
当Pod A(10.1.1.2)向Pod B(10.1.2.3)发送数据时,数据包在内核中的路径如下:
- Pod netns内:进程通过socket发送数据,内核查找Pod路由表,匹配默认路由,从eth0发出。
- veth pair传输:数据包从Pod侧veth1进入,内核通过veth pair的peer指针,直接将数据包推送到宿主机侧veth0的接收队列。此过程不经过物理链路,纯内存拷贝。
- 宿主机netns:数据包到达veth0,触发宿主机网络栈。宿主机路由表判断目标IP 10.1.2.3不在本地,查找Overlay隧道路由,将数据包送入隧道设备。
- 封装与发送:隧道设备添加VXLAN/Geneve头,通过物理网卡发送到对端节点。
XDP日志关联实战: 若XDP程序挂载在宿主机侧veth0上,日志中src_ip=10.1.1.2,dst_ip=10.1.2.3,此时报文为原始Pod报文,无封装头。若XDP程序挂载在物理网卡eth0上,日志中src_ip=192.168.1.10,dst_ip=192.168.1.20,外层UDP端口=4789,此时报文为封装态。根因定位时,必须根据XDP挂载点判断日志中的IP是Pod IP还是节点IP,否则会错误关联流量。
3.4 数据平面各层XDP挂载点与日志特征
| 挂载点位置 | 设备类型 | 报文形态 | 日志中src_ip | 日志中dst_ip | 典型丢包原因 |
|---|---|---|---|---|---|
| Pod侧veth (eth0) | 虚拟网卡 | 原始Pod报文 | Pod IP | Pod IP | Pod内路由错误、ARP失败 |
| 宿主机侧veth | 虚拟网卡 | 原始Pod报文 | Pod IP | Pod IP | 宿主机路由表缺失、策略路由丢弃 |
| 隧道设备 | 虚拟隧道 | 解封装后报文 | Pod IP | Pod IP | VNI不匹配、封装格式错误 |
| 物理网卡 | 物理网卡 | 封装后Overlay报文 | 节点IP | 节点IP | MTU超过1500、UDP校验和错误 |
| 网桥(如cbr0) | 虚拟桥接 | 原始二层帧 | Pod IP | Pod IP | MAC地址学习错误、STP阻塞 |
根因定位避坑指南: 在XDP日志分析中,若发现src_ip为节点IP但内层五元组与Pod预期不符,应优先检查Overlay封装是否正确。常见根因包括:VNI配置错误导致报文被错误节点接收、外层UDP校验和卸载(TSO/GRO)导致XDP捕获到不完整报文、MTU不一致导致分片丢失。建议在XDP程序中同时捕获内层和外层IP,通过bpf_map关联两个维度的信息。