4. 容器网络模型:CNI规范、Pod网络命名空间、veth pair与容器连通性

在深入Cilium缓存命中故障排查之前,必须透彻理解容器网络的基础模型。Cilium作为CNI插件运行,其eBPF程序挂载点、缓存查找路径以及数据包转发逻辑,都直接依赖于Pod网络命名空间、veth pair以及CNI规范的交互方式。本节将拆解这三个核心概念,并展示它们如何协同工作以实现容器连通性。

4.1 CNI规范:容器网络的标准化接口

容器网络接口(Container Network Interface, CNI)是Kubernetes与网络插件之间的契约。它定义了一组标准操作(ADD、DEL、CHECK等)和参数传递格式,使得任何符合CNI规范的插件(如Cilium、Calico、Flannel)都能被Kubernetes kubelet调用。

CNI操作 触发时机 核心职责
ADD Pod创建时 创建网络命名空间、分配IP、配置接口与路由
DEL Pod删除时 清理网络资源、释放IP、删除接口
CHECK 周期性健康检查 验证Pod网络配置是否仍然有效
VERSION 插件初始化时 返回插件支持的CNI规范版本

CNI规范的核心设计原则是可组合性。一个CNI配置可以包含多个插件(通过插件链实现),例如:先由cilium-cni执行主网络配置,再由portmap插件处理主机端口映射。Cilium作为CNI插件,在ADD操作中会完成以下关键步骤:

  1. 接收kubelet传递的Pod名称、命名空间、容器ID等信息。
  2. 创建或获取Pod的网络命名空间(netns)。
  3. 创建veth pair,将一端放入Pod netns,另一端留在主机网络栈。
  4. 为Pod netns内的veth端分配IP地址(通常来自Cilium IPAM)。
  5. 在主机端配置路由规则,将Pod IP的流量导向veth主机端。
  6. 通过eBPF程序(如cilium_net)附加到主机端veth,实现策略执行和转发。
故障排查要点: 当Cilium缓存命中失败时,首先应检查CNI ADD操作是否完整执行。使用 cilium endpoint list 确认Pod的endpoint状态是否为 ready。若状态为 not-ready 或 disconnected,通常意味着CNI配置阶段出现了问题,例如IP分配失败或veth pair创建异常。

4.2 Pod网络命名空间:隔离与独立的网络栈

每个Pod在Kubernetes中拥有独立的网络命名空间(Network Namespace)。这意味着Pod拥有自己的:

  • 网络接口:包括lo回环接口和veth pair的Pod端。
  • 路由表:决定数据包如何从Pod内部发出。
  • ARP表:用于解析同一二层网络内的MAC地址。
  • iptables/nftables规则:Pod内部的网络过滤规则(通常为空)。
  • 套接字(socket):所有网络连接都绑定在Pod的netns内。

这种隔离机制确保了Pod A的网络故障不会直接影响Pod B,同时也为Cilium的eBPF程序提供了清晰的边界。Cilium在主机网络命名空间中运行其代理(cilium-agent),并通过eBPF程序在主机端veth接口上捕获进出Pod的所有流量。

调试技巧: 使用 nsenter 命令可以进入Pod的网络命名空间进行调试。例如:nsenter -t <container-pid> -n ip addr 可以查看Pod内部的IP地址配置。这在排查Pod内部路由或ARP问题时非常有效。

4.3 veth pair:连接Pod与主机的虚拟网线

veth(Virtual Ethernet)pair是一对虚拟网络接口,它们像一根网线的两端:数据包从一端进入,会立即从另一端出来。在容器网络模型中,veth pair扮演着连接Pod网络命名空间与主机网络命名空间的桥梁角色。

典型的veth pair配置如下:

# 主机端接口(通常命名为 lxcXXXX 或 eth0 在主机netns中)
# Pod端接口(通常命名为 eth0 在Pod netns中)

# 查看主机端veth接口
ip link show type veth

# 查看Pod端veth接口(需进入Pod netns)
nsenter -t <container-pid> -n ip link show eth0

veth pair的关键特性:

  • 对称性:两端接口完全对称,没有主从关系。
  • 数据包透传:所有从一端发送的L2帧都会直接出现在另一端。
  • 无内置过滤:veth本身不执行任何网络策略,所有策略由附加的eBPF程序或iptables规则实现。
  • MTU一致性:两端MTU必须一致,否则可能导致分片或丢包。
常见故障场景: 当Cilium缓存命中失败时,检查veth pair的MTU配置是否与底层网络设备匹配。如果主机网卡MTU为1500,而veth pair的MTU被设置为9000(巨型帧),可能导致数据包在主机网卡处被分片,从而触发eBPF程序中的异常路径,影响缓存查找结果。

4.4 容器连通性:从Pod内部到外部的数据流

理解数据包从Pod内部出发,经过veth pair、主机网络栈,最终到达目标的过程,是排查Cilium缓存命中的基础。下图展示了这一完整的数据流路径:

容器连通性数据流:Pod → veth pair → 主机网络 → 目标 Pod 网络命名空间 eth0 (veth端) IP: 10.0.1.2 MAC: 02:42:0a:00:01:02 路由: 默认网关 10.0.1.1 ARP表: 网关MAC veth pair (虚拟网线) 主机网络命名空间 lxcXXXX (veth主机端) IP: 10.0.1.1 (网关) MAC: 02:42:0a:00:01:01 eBPF程序 (tc/xdp) 路由: Pod CIDR → veth 主机网络栈 路由查找 → iptables → 转发 Cilium eBPF 策略检查 物理网卡 eth0 IP: 192.168.1.10 目标服务 IP: 10.96.0.1 Cilium eBPF挂载点 tc ingress/egress 或 XDP

数据流的关键步骤:

  1. Pod内部发送:Pod中的应用通过socket发送数据包,目标IP为10.96.0.1。
  2. 路由决策:Pod netns内的路由表查找,匹配默认网关10.0.1.1,数据包从eth0发出。
  3. veth传输:数据包从Pod端eth0进入veth pair,立即出现在主机端lxcXXXX接口。
  4. eBPF程序处理:Cilium在主机端veth接口上附加了tc或XDP eBPF程序。程序执行缓存查找(如CT map、LB map),决定是转发、丢弃还是执行NAT。
  5. 主机网络栈:如果eBPF程序允许转发,数据包进入主机网络栈,进行路由查找和iptables处理。
  6. 物理出口:最终数据包通过物理网卡eth0发送到外部网络或目标Pod所在节点。

4.5 Cilium视角:eBPF程序与veth的绑定关系

Cilium通过eBPF程序直接附加到主机端的veth接口上,这是实现高性能网络策略和负载均衡的关键。下图展示了Cilium eBPF程序与veth pair的绑定关系:

Cilium eBPF程序与veth pair绑定关系 Pod netns eth0 (veth端) IP: 10.0.1.2 MAC: 02:42:0a:00:01:02 veth 主机 netns lxcXXXX (veth主机端) IP: 10.0.1.1 MAC: 02:42:0a:00:01:01 Cilium eBPF程序 tc ingress: cilium_from_netdev tc egress: cilium_to_netdev XDP: cilium_xdp 缓存命中与eBPF程序的关系 Cilium在主机端veth接口上附加eBPF程序。当数据包到达veth主机端时, eBPF程序首先查找连接跟踪(CT)缓存和负载均衡(LB)缓存。 缓存命中失败通常意味着CT/LB map未正确填充或查找键不匹配。

在Cilium中,eBPF程序通过tc(traffic control)或XDP(eXpress Data Path)附加到veth主机端接口。当数据包从Pod端通过veth到达主机端时,eBPF程序会:

  • 查找连接跟踪缓存(CT map):判断数据包是否属于已有连接。如果命中,直接应用缓存的转发决策。
  • 查找负载均衡缓存(LB map):如果数据包目标是Service IP,查找后端Pod的真实IP。
  • 执行策略检查:根据CiliumNetworkPolicy规则,决定允许或拒绝数据包。
缓存命中故障排查关键点: 当eBPF程序在veth主机端执行缓存查找时,如果CT map或LB map中缺少对应的条目,就会发生缓存未命中。这通常会导致数据包被发送到用户空间的cilium-agent进行慢路径处理,增加延迟。排查时应检查:
1. cilium bpf ct list 查看连接跟踪表是否包含预期的连接。
2. cilium bpf lb list 查看负载均衡表是否包含目标Service的后端映射。
3. 确认veth接口的eBPF程序是否正确加载:tc filter show dev lxcXXXX ingress。

4.6 总结:容器网络模型对Cilium缓存的影响

容器网络模型中的每个组件都可能影响Cilium的缓存命中率:

组件 对缓存命中的潜在影响 排查方向
CNI规范 CNI ADD操作未正确配置IP或路由,导致eBPF程序无法关联endpoint 检查 cilium endpoint list 状态
Pod网络命名空间 Pod netns内路由错误,导致数据包从错误接口发出,绕过eBPF程序 使用 nsenter 检查Pod内部路由表
veth pair MTU不匹配导致分片,eBPF程序无法正确解析L4头部 检查veth MTU与主机网卡MTU是否一致
eBPF程序绑定 eBPF程序未正确附加到veth主机端,导致缓存查找不生效 使用 tc filter show 验证程序加载