第277篇:Cilium eBPF 数据面与网络性能

关键词

Cilium、eBPF、XDP、TC hook、eBPF Map、身份标识、套接字级路由、Hubble、高性能网络


一、eBPF 技术基础

1.1 eBPF 是什么

eBPF(extended Berkeley Packet Filter)是一种在内核中安全运行沙箱程序的技术:

eBPF 架构:

用户态 Cilium Agent bpftool ── 加载 eBPF 程序 ──┐
内核态 ┌──────────────┐ └──────────────┘ ┌──────────────┐ └──────────────┘ ┌─── eBPF Map ──────────────────────┐ └───────────────────────────────────┘ ┌─── eBPF Hook 点 ──────────────────┐ eBPF Verifier JIT Compiler Pod 标识映射 策略规则 连接跟踪 XDP(网卡驱动层) TC(网络栈) cgroup(套接字) tracepoint
--- ---

eBPF 的关键特性: 1. 安全——Verifier 检查所有程序确保不会崩溃内核 2. 高性能——JIT 编译为本地代码,无解释执行 3. 动态加载——不重启内核或重启系统 4. 可编程——按需加载卸载

1.2 eBPF Hook 点

Cilium 使用的 eBPF Hook 点:

网卡硬件 XDP (eXpress Data Path) ┌────────────────────────────────┐ └────────────────────────────────┘ TC (Traffic Control) ingress/egress ┌────────────────────────────────┐ └────────────────────────────────┘ cgroup/sock ┌────────────────────────────────┐ 在网卡驱动层,SKB 分配之前 处理后直接决定: - XDP_PASS:送到内核协议栈 - XDP_DROP:直接丢弃(最快) - XDP_TX:从原端口发回 在内核协议栈中,SKB 分配后 可以修改数据包内容 可以做路由和转发决策 在套接字层(connect/bind/send) 实现套接字级路由和策略

性能对比(PPS): XDP:20M+ pps(不分配 SKB,最轻量) TC:15M pps(分配 SKB,但无 iptables 遍历) iptables:5M pps(规则链遍历)


二、Cilium eBPF 数据面

2.1 数据包路径

Cilium eBPF 数据面——Pod 到 Pod 的数据包路径:

同节点 Pod 通信:

  PodA ──► vethA ──► TC ingress(eth0入口)
                    │
                    ├─ 查找 eBPF Map:目标 identity
                    ├─ 策略检查:允许?
                    ├─ 查找转发信息:目标 MAC
                    │
                    └─ TC egress(vethB出口)
                         └─► PodB

  无 iptables!2 次 eBPF 程序完成全部处理

跨节点 Pod 通信:

  PodA ──► vethA ──► TC ingress
                    │
                    ├─ 查找 eBPF Map
                    ├─ 策略检查
                    ├─ 封装 VXLAN/Geneve(或直接路由)
                    │
                    └─ XDP / TC(物理网卡出口)
                         └─► 物理网络 ──► 目标节点

  封装开销仅一次
  不需要经过 iptables PREROUTING/FORWARD/POSTROUTING 链

2.2 身份标识(Identity)

Cilium 使用基于标签的身份标识(Security Identity)替代 IP 地址做策略:

传统 iptables 策略:
  -A FORWARD -s 10.1.1.0/24 -d 10.1.2.0/24 -j ACCEPT

  问题:Pod IP 变化时需要更新规则
        规则随 Pod 数量线性增长

Cilium Identity:
  每个 Pod 根据标签分配一个身份标识(24-bit ID)

  PodA:app=web, env=prod → Identity: 1001
  PodB:app=db, env=prod → Identity: 1002

  eBPF Map 中的策略:
    Identity 1001 → 可以访问 1002:3306
    Identity 1002 → 可以接受来自 1001 的 3306

  数据包处理:
    从 veth 进入后,提取 Pod 的 Identity
    查 eBPF Map:srcID=1001, dstID=1002, port=3306 → ALLOW

  优势:
    Pod IP 变化不影响策略
    策略不随 Pod 数量增长
    支持 L7 策略(HTTP 方法、路径等)

2.3 eBPF Map

Cilium 使用 eBPF Map 存储网络状态(替代内核 conntrack 和路由表):

核心 eBPF Maps:

Map 名称 存储内容
cilium_lxc cilium_ct4 cilium_ct6 cilium_policy cilium_ipcache cilium_tunnel_map cilium_lb_services cilium_lb_backends 本地 Pod 的 MAC/IP/Identity 连接跟踪表(IPv4) 连接跟踪表(IPv6) 策略规则(Identity → 规则) IP 到 Identity 映射 隧道端点映射 Service 负载均衡表 后端 Pod 列表

eBPF Map 的优势: 1. 内核空间——查找无需切换到用户态 2. 哈希表——O(1) 查找 3. 原子操作——无锁并发访问 4. 可观测——bpftool map dump 可读

查看 eBPF Maps: bpftool map show bpftool map dump id 123


三、Cilium 网络性能

3.1 性能提升的关键

Cilium eBPF 提升网络性能的六个关键点:

1. 绕过 iptables
   传统:数据包遍历 5 个 hook × N 条规则
   Cilium:2 次 eBPF 程序查找(入口 + 出口)

2. 绕过 conntrack
   传统:内核 conntrack 维护连接状态(大量锁竞争)
   Cilium:eBPF Map 存储(无锁或 Per-CPU)

3. 套接字级负载均衡
   Cilium 的 kube-proxy 替代:
     在 connect() 系统调用时直接选择后端
     无需 DNAT → 避免 conntrack
     减少 50% 延迟

4. XDP 早期丢包
   不需要的包在网卡驱动层丢弃
   不分配 SKB → 零内存开销

5. Per-CPU 数据结构
   eBPF Map 使用 Per-CPU 布局
   无锁竞争 → 多核线性扩展

6. 编译为本地代码
   JIT 编译 → 与内核代码相同性能
   无解释开销

3.2 性能测试数据

Cilium eBPF vs iptables 性能对比(Intel Xeon 100G NIC):

测试 1:Pod-to-Pod 吞吐(TCP 双向)

包大小 iptables Cilium 提升
64B 256B 1024B 9000B 5 Gbps 18 Gbps 45 Gbps 85 Gbps 18 Gbps 40 Gbps 70 Gbps 94 Gbps 260% 122% 55% 10%

小包场景提升最明显(iptables 的规则遍历开销占比大)

测试 2:每秒新建连接数

iptables:30K conntrack Cilium eBPF:200K+ 提升:6x

原因:conntrack 锁竞争被 eBPF Per-CPU Map 消除

测试 3:Service(Cluster IP)延迟

iptables kube-proxy: 数据包经过 PREROUTING → DNAT → FORWARD → POSTROUTING 延迟:~60μs

Cilium eBPF 套接字级: connect() 系统调用时直接确定后端 延迟:~10μs

提升:80%

3.3 Hubble 可观测性

Hubble——Cilium 的网络可观测性组件:

核心能力:

  1. 服务地图(Service Map)
     自动发现服务间依赖关系
     可视化微服务通信拓扑

  2. 流量监控
     实时每秒/每分钟流量指标
     按 Pod/Service/Namespace 分类

  3. 延迟分析
     每跳延迟分布(P50/P90/P99)
     识别慢路径

  4. 策略审计
     哪些策略被触发
     哪些流量被拒绝(Drop 原因)

  # 使用 Hubble CLI
  hubble observe --from-pod default/web-xxx --to-pod default/db-yyy
  hubble observe --verdict DROPPED              # 查看被拒绝的流量

  # 实时监控
  hubble status
  hubble metrics --match "http_requests_total" --match "drop_total"

四、Cilium Service 替代

4.1 eBPF kube-proxy 替代

Cilium 可以完全替代 kube-proxy(性能更好):

传统 kube-proxy iptables 模式:

  客户端 Pod → 10.96.0.10:80
    ┌─ PREROUTING: DNAT 10.96.0.10 → 10.1.1.2
    ├─ FORWARD: 检查
    ├─ POSTROUTING: SNAT(如果需要)
    └─ 发送到 10.1.1.2:8080

  延迟:~60μs

Cilium eBPF 套接字级:

  客户端 Pod 调用 connect("10.96.0.10", 80)
    ┌─ cgroup/sock eBPF 程序
    ├─ 查 eBPF Map:Service 10.96.0.10 → 后端列表
    ├─ 选择后端:10.1.1.2:8080
    ├─ 修改 sock 结构体:目标改为 10.1.1.2:8080
    └─ 后续数据包直接发到 10.1.1.2:8080

  延迟:~10μs(减少 80%)
  无需 DNAT → 无需 conntrack

五、总结

知识点 核心要点
eBPF 内核沙箱,安全运行用户加载的程序
XDP 网卡驱动层 hook,早期丢包/转发,PPS 最高
TC hook 网络栈中 hook,可修改数据包
身份标识 基于标签的 Security Identity,替代 IP 做策略
eBPF Map 内核哈希表存储状态,O(1) 查找,无锁
性能提升 绕 iptables、绕 conntrack、套接字级 LB
Hubble 可观测性,服务地图、延迟分析、策略审计
Service 替代 eBPF 套接字级 LB,延迟降低 80%

六、思考

  1. eBPF 程序在内核中是如何安全运行的?Verifier 检查哪些方面?
  2. XDP 和 TC hook 的区别是什么?什么场景应该用 XDP,什么场景用 TC?
  3. Cilium 的 Security Identity 相比 IP 地址做策略有什么优势?Identity 是如何分配的?
  4. Cilium 如何实现 kube-proxy 替代?套接字级负载均衡相比 iptables DNAT 为什么性能更好?
  5. 如果发现某个 Pod 的网络延迟异常高(P99 > 100ms),如何使用 Hubble 定位问题?

下篇预告:第278篇《K8s Ingress 与 Service Mesh 网络》——从 Ingress Controller 到 Service Mesh,K8s 流量入口管理的发展与 Istio/Linkerd 的 sidecar 代理原理。