2. eBPF技术基础:eBPF架构、eBPF程序类型、eBPF Map、eBPF在Cilium中的应用

eBPF(extended Berkeley Packet Filter)是Linux内核中一种革命性的沙箱技术,允许用户在不修改内核源码或加载内核模块的情况下,安全高效地在内核空间运行自定义程序。Cilium正是基于eBPF实现了网络、可观测性与安全策略。理解eBPF是掌握Cilium通信机制的前提。

2.1 eBPF架构

eBPF架构由用户空间、内核验证器/即时编译器(JIT)以及内核钩子三部分组成。程序通过系统调用(bpf())加载,经过严格验证后由JIT编译为原生机器码执行。

核心架构组件:
  • 用户空间加载器:使用libbpf或bpftool将eBPF字节码注入内核。
  • 内核验证器:静态分析字节码,确保无循环、无越界、无非法指针访问,保证系统安全。
  • JIT编译器:将通用字节码转换为特定CPU架构的机器码,提升执行效率。
  • 内核钩子:程序附着点,如网络数据包、系统调用、跟踪点、性能事件等。
  • eBPF Map:用户空间与内核空间、以及不同eBPF程序之间的数据交换通道。
eBPF 架构总览 用户空间 bpftool / libbpf eBPF 字节码 内核验证器 静态分析 安全校验 JIT 编译器 原生机器码 高性能执行 内核钩子(Hook Points) XDP TC Ingress/Egress Tracepoint Kprobe/Uprobe cgroup / Socket Filter eBPF Map(数据交换层) Hash / Array / LRU / Per-CPU

2.2 eBPF程序类型

eBPF程序类型决定了其附着点和可访问的上下文。Cilium主要使用以下几种类型:

程序类型 附着点 Cilium中的用途
BPF_PROG_TYPE_XDP 网卡驱动层(最早钩子) DDoS防护、负载均衡、早期丢包
BPF_PROG_TYPE_SCHED_CLS TC(Traffic Control)入/出方向 Pod网络策略、封装/解封装(VXLAN/Geneve)
BPF_PROG_TYPE_CGROUP_SOCK cgroup套接字操作 Socket级策略、DNS策略控制
BPF_PROG_TYPE_KPROBE 内核函数动态探针 可观测性、故障注入、性能追踪
BPF_PROG_TYPE_TRACING 内核静态跟踪点 Hubble可观测性数据采集
关键区别:XDP程序在网卡驱动层处理数据包,性能最高但上下文有限;TC程序在协议栈中处理,可修改数据包内容,是Cilium网络策略的核心实现点。

2.3 eBPF Map

eBPF Map是内核空间与用户空间、以及不同eBPF程序之间共享数据的核心数据结构。Map类型决定了存储方式和访问性能。

常用Map类型对比

Map类型 数据结构 典型场景
BPF_MAP_TYPE_HASH 哈希表(Key-Value) 连接跟踪表、策略规则查找
BPF_MAP_TYPE_ARRAY 固定大小数组 全局计数器、统计指标
BPF_MAP_TYPE_LRU_HASH LRU淘汰哈希表 会话表、缓存(自动淘汰旧条目)
BPF_MAP_TYPE_PERCPU_HASH Per-CPU哈希表 高性能计数器(无锁竞争)
BPF_MAP_TYPE_RINGBUF 环形缓冲区 事件日志、可观测性数据传递
// 示例:使用libbpf创建Hash Map
struct bpf_map_def SEC("maps") my_map = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(u32),
    .value_size = sizeof(struct my_value),
    .max_entries = 65536,
};

2.4 eBPF在Cilium中的应用

Cilium将eBPF的能力系统化地应用于容器网络的每个环节,实现了高性能、可编程的数据平面。

eBPF 在 Cilium 中的应用场景 Cilium Agent eBPF 程序编排 网络 Pod IP路由 VXLAN/Geneve封装 安全策略 L3/L4/L7策略 Identity-based 隔离 可观测性 Hubble 事件流 服务拓扑可视化 负载均衡 XDP/TC 负载均衡 Maglev一致性哈希 带宽管理 EDT 速率限制 Pod 带宽保证

Cilium中eBPF的关键应用细节

  • 网络策略执行:Cilium在TC Ingress/Egress钩子中加载eBPF程序,通过bpf_map_lookup_elem()查询Identity Map,实现基于安全身份的L3/L4/L7策略,无需iptables规则遍历。
  • 服务负载均衡:利用XDP程序在网卡驱动层直接完成DNAT和反向转换,实现每秒百万级新建连接,延迟降低至微秒级。
  • 连接跟踪:使用LRU_HASH Map维护连接跟踪表,支持NAT和策略状态跟踪,避免内核conntrack的性能瓶颈。
  • Hubble可观测性:通过Tracepoint和Kprobe程序捕获网络事件,使用Ringbuf Map将事件高效传递到用户空间的Hubble组件。
注意事项:eBPF程序受内核验证器严格限制,如循环次数上限(最大4096条指令)、栈大小(512字节)、Map访问必须边界检查。Cilium在加载程序时会自动处理这些约束,但自定义eBPF程序时需特别注意。

eBPF程序生命周期管理

阶段 操作 Cilium对应组件
编译 将C代码编译为eBPF字节码(.o文件) clang + LLVM 后端
加载 通过bpf()系统调用加载到内核 cilium-agent (libbpf)
验证 内核验证器检查安全性 Linux Kernel Verifier
附着 将程序绑定到指定钩子 cilium-agent (netlink)
运行 事件触发时执行eBPF程序 内核事件驱动
卸载 从钩子分离并释放资源 cilium-agent / bpftool