4、Cilium数据面原理:基于eBPF的L3/L4网络策略、Service负载均衡(DSR与Tunnel模式)、NAT与封装

Cilium 的数据面完全构建在 eBPF 之上,绕过了传统的 iptables 和内核网络栈的复杂路径。本章深入解析其核心数据面组件:L3/L4 网络策略的 eBPF 实现、Service 负载均衡的两种模式(DSR 与 Tunnel),以及 NAT 与封装的底层机制。

4.1 基于eBPF的L3/L4网络策略

Cilium 的网络策略通过 eBPF 程序直接挂载到网络钩子点(如 XDP、TC ingress/egress)实现,无需修改 iptables 规则。每个节点上的 Cilium Agent 将用户定义的策略(CRD)编译为 eBPF 字节码,并加载到内核。

关键原理: 策略执行点位于 Endpoint(Pod 的虚拟网卡)的 eBPF 程序上。每个数据包在进入或离开 Pod 时,都会被对应的 eBPF 程序检查,匹配策略中的 L3(源/目的 IP、标签)和 L4(端口、协议)规则。

策略匹配流程如下:

  1. 身份识别: 数据包到达 Endpoint 时,eBPF 程序提取源/目的 IP,通过全局的 Identity Map 转换为安全标签(Security Identity)。
  2. 策略查找: 使用源身份、目的身份、目的端口和协议作为 Key,在 eBPF Map 中查找对应的策略决策(Allow / Deny)。
  3. 动作执行: 若匹配到 Allow 规则,数据包继续处理;若匹配到 Deny 或无匹配,则直接丢弃。
性能优势: 由于 eBPF Map 查找是 O(1) 复杂度的哈希表操作,且策略执行发生在数据包最早期的处理阶段(XDP 或 TC),Cilium 的 L3/L4 策略延迟通常低于 1 微秒,远优于 iptables 的线性规则遍历。
Cilium L3/L4 网络策略 eBPF 执行流程 Cilium L3/L4 网络策略 eBPF 执行流程 数据包到达 身份提取 策略 Map 查找 决策 允许 (Allow) 丢弃 (Drop) 说明:身份提取依赖全局 Identity Map,策略查找使用哈希表,确保 O(1) 性能。

4.2 Service负载均衡:DSR与Tunnel模式

Cilium 为 Kubernetes Service 提供两种负载均衡转发模式:DSR(Direct Server Return) 和 Tunnel(隧道)。两者均通过 eBPF 在节点上完成,无需 kube-proxy。

特性 DSR 模式 Tunnel 模式
转发路径 请求经 LB 节点,响应直接返回客户端 请求和响应均经过 LB 节点
后端可见源 IP 客户端真实 IP(保留源 IP) LB 节点 IP(需额外配置保留源 IP)
封装开销 无封装,性能最高 需要 VXLAN/Geneve 封装,有额外开销
适用场景 对性能要求极高,且网络允许直接路由 跨子网、跨集群、网络策略隔离要求高
eBPF 实现 在 TC 入口修改目标 MAC 为后端 Pod MAC 在 TC 入口封装外层隧道头

4.2.1 DSR 模式

在 DSR 模式下,Cilium 的 eBPF 程序在负载均衡节点上仅修改数据包的 目标 MAC 地址 为后端 Pod 的 MAC,并转发出去。后端 Pod 处理完请求后,直接以客户端 IP 为目标发送响应,绕过负载均衡节点。

关键 eBPF 操作: bpf_redirect() 将数据包重定向到后端 Pod 所在的网络设备,同时通过 bpf_skb_store_bytes() 修改 MAC 头。源 IP 和目的 IP(Cluster IP)保持不变。

4.2.2 Tunnel 模式

Tunnel 模式下,Cilium 在源节点将原始数据包封装在 VXLAN 或 Geneve 隧道中,目标节点解封装后转发给后端 Pod。响应数据包同样经过隧道返回源节点,再由源节点解封装后发送给客户端。

注意: Tunnel 模式虽然增加了封装/解封装的开销(约 5-10% 性能损耗),但它提供了更好的网络隔离性,并且不依赖底层网络的路由配置,适合 Overlay 网络环境。
DSR 与 Tunnel 模式对比 DSR 与 Tunnel 模式对比 DSR 模式 客户端 LB 节点 后端 Pod 响应直接返回客户端 Tunnel 模式 客户端 源节点 隧道封装 目标节点 后端 Pod 响应经隧道返回源节点,再转发给客户端

4.3 NAT与封装

Cilium 的 NAT 和封装功能同样由 eBPF 程序实现,用于处理 Service 的 DNAT(目标网络地址转换)和 Overlay 网络的隧道封装。

4.3.1 NAT 实现

当数据包匹配到 Service 规则时,eBPF 程序在 TC ingress 点执行 DNAT,将目标 IP 从 Cluster IP 转换为后端 Pod IP。转换信息记录在 NAT Map 中,用于反向转换(SNAT)。

  • DNAT: 修改数据包的目标 IP 和端口,通过 bpf_skb_store_bytes() 和 bpf_l3_csum_replace() 更新校验和。
  • SNAT: 对于非 DSR 模式,响应数据包经过 LB 节点时,将源 IP 从 Pod IP 转换回 Cluster IP。
  • Map 结构: NAT Map 使用 struct ipv4_nat_entry 存储原始 IP:端口与转换后 IP:端口的映射,支持并发查找。

4.3.2 封装实现

在 Tunnel 模式下,Cilium 使用 VXLAN 或 Geneve 封装。eBPF 程序在源节点创建外层 UDP 头(VXLAN 端口 8472,Geneve 端口 6081),并将原始数据包作为负载。

eBPF 封装关键步骤:
// 伪代码示例:VXLAN 封装
1. 计算外层头部长度(ETH + IP + UDP + VXLAN)
2. 通过 bpf_skb_adjust_room() 扩展数据包头部空间
3. 填充外层以太网头(目标 MAC 为隧道端点)
4. 填充外层 IP 头(源 IP 为本节点,目标 IP 为远端节点)
5. 填充 UDP 头(源端口为哈希值,目标端口 8472)
6. 填充 VXLAN 头(VNI 为网络标识)
7. 通过 bpf_redirect() 发送到隧道设备
性能调优提示: 封装操作会增加 CPU 开销,尤其是在高吞吐场景下。建议在 Cilium 中启用 BPF 校验和卸载(通过 ethtool 启用网卡 TX checksum offload),可减少约 30% 的封装 CPU 消耗。

下表总结了 NAT 与封装在不同模式下的行为差异:

功能 DSR 模式 Tunnel 模式
DNAT 仅在 LB 节点执行一次 在源节点执行
SNAT 不需要(响应直接返回) 在源节点执行(响应返回时)
封装 无 VXLAN/Geneve 封装
eBPF Map 使用 NAT Map(仅 DNAT 条目) NAT Map + Tunnel Map(端点映射)