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程序链(按执行顺序):
- tc ingress (veth宿主机端):数据包从容器进入宿主机后的第一个BPF程序。负责早期过滤、策略检查和本地连接跟踪。
- XDP (物理网卡):仅在跨节点通信时生效,在网卡驱动层进行早期转发或封装。
- tc egress (物理网卡):数据包离开宿主机前的最后一个BPF程序,负责封装(VXLAN/Geneve)和路由。
- tc ingress (目标宿主机物理网卡):目标节点接收数据包后的第一个BPF程序,负责解封装和策略检查。
- 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程序挂载点和命名空间边界:
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指标,快速定位缓存问题。