3. eBPF 核心技术概览:程序类型、BPF 映射、辅助函数、CO-RE 与 BTF

eBPF 并非单一技术,而是一套由程序类型、映射、辅助函数以及加载验证机制构成的完整生态。理解这四大核心组件,是掌握 eBPF 在 HPA 与灰度门禁场景中应用的基础。

3.1 eBPF 程序类型:挂载点决定能力

eBPF 程序必须挂载到内核的特定事件点(kprobe、tracepoint、XDP、cgroup 等)才能执行。不同的程序类型决定了你能捕获什么数据、在哪个网络或系统层级工作。

程序类型 挂载点 典型用途 HPA/灰度场景价值
kprobe/kretprobe 内核函数入口/返回 监控系统调用、函数参数 捕获容器 CPU 调度、内存分配
tracepoint 内核静态跟踪点 稳定、低开销的指标采集 采集 cgroup 统计、网络事件
XDP 网卡驱动层 高速包过滤、负载均衡 灰度流量标记、早期丢弃
TC (clsact) 内核协议栈 流量整形、QoS 灰度流量限速、重定向
cgroup/skb cgroup 层级 容器网络策略 按 Pod 粒度控制出站流量
perf_event PMU/软件事件 性能采样、CPU 分析 实时热点检测,辅助弹性决策
选型建议: 在 HPA 场景中,优先使用 tracepoint 和 cgroup/skb 类型,因为它们接口稳定、对内核版本依赖低;灰度门禁中,XDP 和 TC 是流量标记与过滤的首选。

3.2 BPF 映射:内核态与用户态的数据桥梁

BPF 映射(Map)是 eBPF 程序的核心数据结构,用于在内核态与用户态之间共享状态、统计计数、配置规则。映射类型决定了数据组织方式与并发语义。

映射类型 键/值 特点 HPA/灰度场景示例
BPF_MAP_TYPE_HASH 任意 通用哈希表,支持动态增删 存储 Pod IP → 灰度标签映射
BPF_MAP_TYPE_ARRAY 整数索引 固定大小,快速随机访问 存储 CPU 使用率统计数组
BPF_MAP_TYPE_PERCPU_HASH 任意 Per-CPU 哈希,无锁高性能 按 CPU 核聚合容器指标
BPF_MAP_TYPE_RINGBUF 事件流 高性能环形缓冲区,替代 perf_event 实时推送 Pod 弹性事件
BPF_MAP_TYPE_STACK_TRACE 栈 ID 存储调用栈,用于 profiling 诊断 HPA 误触发根因
// 示例:定义灰度标签映射(C 伪代码)
struct bpf_map_def SEC("maps") gray_map = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(u32),          // Pod IP (host order)
    .value_size = sizeof(struct gray_rule),
    .max_entries = 1024,
};

// 用户态更新映射
int key = pod_ip;
struct gray_rule rule = { .canary = 1, .weight = 30 };
bpf_map_update_elem(&gray_map, &key, &rule, BPF_ANY);

3.3 辅助函数:安全的内核能力调用

eBPF 程序不能直接调用内核函数,必须通过辅助函数(Helper) 完成数据读取、映射操作、事件输出等任务。每个程序类型都有允许调用的辅助函数白名单。

  • 数据获取类: bpf_get_current_pid_tgid()、bpf_get_current_cgroup_id()、bpf_skb_load_bytes()
  • 映射操作类: bpf_map_lookup_elem()、bpf_map_update_elem()、bpf_map_delete_elem()
  • 事件输出类: bpf_perf_event_output()、bpf_ringbuf_output()
  • 辅助计算类: bpf_ktime_get_ns()、bpf_get_prandom_u32()
注意: 辅助函数签名在不同内核版本间可能变化。使用 CO-RE 技术后,eBPF 程序会自动重定位辅助函数偏移,无需为每个内核版本重新编译。

3.4 CO-RE 与 BTF:一次编译,到处运行

传统 eBPF 程序需要为每个目标内核版本编译,维护成本极高。CO-RE(Compile Once – Run Everywhere)配合 BTF(BPF Type Format)解决了这一痛点。

核心原理: 编译器在 eBPF 字节码中记录重定位信息(字段偏移、结构体大小),加载器(libbpf)在运行时根据目标内核的 BTF 信息修正这些偏移,实现跨内核兼容。
CO-RE 编译与加载流程 eBPF C 源码 Clang/LLVM 编译 .o 字节码 + BTF libbpf 加载器 目标内核 BTF 信息 修正后的 BPF 程序 关键优势: • 编译时记录结构体字段偏移(BTF),运行时自动修正 • 无需为每个内核版本单独编译,降低运维复杂度 • 加载器校验 BTF 兼容性,不匹配时优雅降级

3.5 BTF:让内核数据结构自描述

BTF(BPF Type Format)是 CO-RE 的基石。它将内核数据结构(struct、union、enum)的布局信息以紧凑的二进制格式嵌入到 eBPF 对象中。加载器通过 BTF 可以精确知道每个字段的偏移量、大小和对齐方式。

// 查看内核 BTF 信息(需安装 bpftool)
# bpftool btf dump file /sys/kernel/btf/vmlinux format c | head -30

// 查看 eBPF 对象中的 BTF 重定位记录
# bpftool prog show --pretty <prog_id>
实战要点: 在 HPA 灰度门禁项目中,我们使用 vmlinux.h 头文件(由 BTF 生成)来引用内核结构体,配合 SEC("tp/...") 宏定义 tracepoint,实现跨内核版本的指标采集。这是课程后续实战章节的基础。

3.6 核心技术关系总结

技术组件 角色 与 HPA 灰度门禁的关系
程序类型 定义挂载点与能力边界 选择 cgroup/skb 控制 Pod 流量,选择 tracepoint 采集指标
BPF 映射 内核态与用户态数据交换 存储灰度规则、Pod 指标、弹性策略
辅助函数 安全调用内核功能 获取 cgroup ID、输出事件到用户态
CO-RE + BTF 跨内核版本兼容 确保 eBPF 程序在 Kubernetes 集群不同节点内核上一致运行