4. 容器网络数据路径:从Pod到Pod的完整数据包流转

理解Cilium缓存命中瓶颈,首先需要精确掌握容器网络的数据路径。当集群中一个Pod向另一个Pod发送数据包时,数据包会穿越多个网络命名空间、虚拟设备以及eBPF程序挂载点。本节将拆解这一完整路径,重点分析veth对、BPF程序链与网络命名空间三个核心要素的交互关系。

4.1 数据路径全景:Pod到Pod的七跳

在Kubernetes集群中,同节点Pod间通信与跨节点Pod间通信的路径存在差异。下表对比了两种场景下的关键路径节点:

路径阶段 同节点Pod通信 跨节点Pod通信
1. 源Pod网络栈 容器内eth0 → 协议栈 容器内eth0 → 协议栈
2. veth对穿越 veth0 → 宿主机veth1 veth0 → 宿主机veth1
3. 宿主机BPF入口 tc ingress (veth1) tc ingress (veth1)
4. 路由决策 本地路由表 → 直接交付 路由表 → 下一跳网关
5. 封装/转发 无封装,直接桥接 VXLAN/Geneve 封装
6. 目标BPF入口 tc ingress (目标veth) 物理网卡 → 解封装 → tc ingress
7. 目标Pod网络栈 宿主机veth → 容器eth0 宿主机veth → 容器eth0
关键洞察: 无论同节点还是跨节点,veth对和tc ingress BPF程序都是必经之路。Cilium在这两个挂载点注入eBPF程序,实现策略执行、负载均衡和转发加速。

4.2 veth对:容器与宿主机之间的数据通道

veth(Virtual Ethernet)是一对虚拟网卡,总是成对出现。一端位于容器网络命名空间(通常命名为eth0),另一端位于宿主机根命名空间(通常命名为lxcxxxxx或calixxxxx)。数据包从一端进入,立即从另一端原样流出,不经过任何协议栈处理。

veth对的关键特性:

  • 零协议栈穿透:数据包在veth对之间传输时,不经过发送端或接收端的TCP/IP协议栈,仅做简单的设备队列转发。
  • 命名空间隔离:veth对的两端分别属于不同的网络命名空间,是容器网络隔离的基础设施。
  • BPF挂载点:在宿主机端的veth设备上,Cilium通过tc hook挂载eBPF程序,实现数据包的早期拦截。

4.3 BPF程序链:数据包在宿主机上的处理流水线

Cilium在宿主机网络路径上构建了一条BPF程序链,每个程序负责一个特定的处理阶段。数据包依次经过这些程序,形成流水线处理模型。

典型的BPF程序链(按执行顺序):

  1. tc ingress (veth宿主机端):数据包从容器进入宿主机后的第一个BPF程序。负责早期过滤、策略检查和本地连接跟踪。
  2. XDP (物理网卡):仅在跨节点通信时生效,在网卡驱动层进行早期转发或封装。
  3. tc egress (物理网卡):数据包离开宿主机前的最后一个BPF程序,负责封装(VXLAN/Geneve)和路由。
  4. tc ingress (目标宿主机物理网卡):目标节点接收数据包后的第一个BPF程序,负责解封装和策略检查。
  5. tc ingress (目标veth宿主机端):数据包进入目标容器前的最后一个BPF程序,负责最终策略执行和连接跟踪更新。
性能提示: BPF程序链的长度直接影响数据包处理延迟。Cilium通过程序链剪枝技术,在不需要某些功能时(如无网络策略的Pod)跳过对应BPF程序,减少不必要的处理开销。

4.4 网络命名空间:隔离与穿越

每个Pod拥有独立的网络命名空间,包含自己的路由表、ARP表、netfilter规则和网络设备。数据包穿越命名空间边界时,需要经过以下关键步骤:

  • 命名空间A(源Pod):数据包在容器内协议栈完成TCP/UDP封装,通过eth0发送。
  • veth对穿越:数据包从容器eth0直接到达宿主机端veth,不经过宿主机协议栈。
  • 命名空间B(宿主机根命名空间):数据包进入宿主机网络栈,经过路由查找、BPF程序处理、可能的封装后,通过物理网卡或目标veth发送。
  • 命名空间C(目标Pod):数据包通过目标veth进入容器,在容器协议栈完成最终交付。

4.5 完整数据路径SVG图

下图展示了同节点Pod-to-Pod通信的完整数据路径,包含veth对、BPF程序挂载点和命名空间边界:

同节点Pod-to-Pod数据路径与BPF程序链 同节点Pod-to-Pod数据路径与BPF程序链 命名空间 A (源Pod) 容器 eth0 TCP/IP 协议栈 veth 宿主机端 命名空间 B (宿主机根命名空间) tc ingress BPF 路由决策 命名空间 C (目标Pod) 容器 eth0 TCP/IP 协议栈 veth对穿越 BPF入口 本地交付 说明: 数据包从源Pod eth0出发,经过veth对直接进入宿主机根命名空间,在tc ingress BPF程序处完成连接跟踪与策略检查, 然后通过路由决策直接交付到目标Pod的veth宿主机端,最终进入目标Pod的协议栈。整个过程不经过宿主机TCP/IP协议栈。 缓存命中瓶颈点: BPF程序中的连接跟踪表(CT Map)查找、策略规则匹配、路由缓存查询均可能成为性能瓶颈,尤其在Pod密度高、连接数大的场景下。

4.6 跨节点数据路径补充:封装与解封装

当Pod位于不同节点时,数据路径在宿主机路由决策后增加封装/解封装阶段。Cilium默认使用VXLAN或Geneve隧道技术,将原始数据包封装在UDP中传输。

跨节点路径的额外步骤:

  • 源节点:路由决策后,BPF程序将数据包封装为VXLAN/Geneve格式,添加外层UDP头和IP头。
  • 物理网络:封装后的数据包通过underlay网络(物理网络)传输到目标节点。
  • 目标节点:物理网卡接收后,XDP或tc ingress BPF程序解封装,还原原始数据包。
性能陷阱: 封装/解封装操作会额外消耗CPU周期,并增加数据包长度(VXLAN增加50字节,Geneve增加50-260字节)。当MTU配置不当或封装卸载(TSO/GRO)未启用时,可能导致严重的性能下降和缓存命中率降低。

4.7 数据路径中的缓存命中关键点

从上述数据路径可以看出,以下环节是Cilium缓存命中的核心瓶颈点:

缓存类型 位置 影响 瓶颈风险
连接跟踪表 (CT Map) tc ingress BPF 决定数据包是否属于已有连接 高
策略映射表 (Policy Map) tc ingress BPF 决定数据包是否允许通过 中
路由缓存 路由决策阶段 加速下一跳查找 中
封装端点缓存 封装/解封装BPF 加速隧道端点查找 低-中
实践建议: 在分析Cilium缓存命中瓶颈时,应优先关注连接跟踪表的命中率。使用cilium bpf ct list命令可以查看当前连接跟踪表的大小和条目数,结合cilium metrics观察cilium_ct_lookup_total和cilium_ct_miss_total指标,快速定位缓存问题。