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程序之间的数据交换通道。
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的能力系统化地应用于容器网络的每个环节,实现了高性能、可编程的数据平面。
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 |