libbpf, bcc和bpftrace的结构和关联分析

  • libbpf bcc 和 bpftrace之间的结构以及和内核的关联

libbpf bcc 和 bpftrace之关系结构图(仅参考)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
+-----------------------------------------------------------------------------+
| 用户空间 (User Space) |
|-----------------------------------------------------------------------------|
| [高层抽象/工具] |
| |
| +-----------------+ |
| | bpftrace(C++) | |
| | (诊断与排障语言)| |
| +-------+---------+ |
| | |
| 内部解析器解析用户脚本,翻译成C代码 |
| 将这个C代码实时编译成 eBPF 字节码(Clang/LLVM) |
| 使用 libbpf 的C API 来加载和管理eBPF程序 |
| | |
| | +----------------+ |
| | |BCC(内部实现C++)| python/Lua/c++高级语言封装|
| | | (快速原型框架) | header file |
| |Clang/LLVM +-------------+--+ |
| | | |
| | 运行时把c代码编译成eBPF字段,API加载交互 |
| | 还是写C,只是编译和加载被Python框架封装了 |
| | | Clang/LLVM |
| +---------------------------+ ---------------------- |
| | libbpf(C) | | |
| | (是纯C开发库, 提供CO-RE) |------------------------------------ |
| | 封装bpf()和Maps API) | | |
| +-------------+-------------+ | |
| | |
| BPF Maps (e.g., RingBuf, Hash) | System Call |
| <------------------------------------------------------> (bpf()) |
| (内核与用户空间的数据通道) | (控制与加载) |
| | |
+------------------------------------------------------------+----------------+
| 内核空间 (Kernel Space) | |
|-----------------------------------------------------------------------------|
| | |
| BPF Maps (内核中的键值对存储) <-----------------------------+ |
| | | |
| +---------------------------------------------------+<---| | |
| | eBPF 子系统 | | |
| | | | |
| | +-----------+ +----------+ +-----------+ | | |
| | | Verifier | --> | JIT | --> | CPU | | | |
| | | (安全检查)| | (编译优化) | | (原生执行)| | | |
| | +-----------+ +----------+ +-----------+ | | |
| | | | |
| | ebpf 程序 (你的.bpf.c代码) | | |
| | | | |
| +-----------------------+---------------------------+ | |
| ^ | |
| | (事件触发) (读取/写入)| |
| | v |
| +-----------------------+-------------------------------------------+ |
| | 内核钩子 (kernel hooks) | |
| | | |
| | ftrace (kprobes, tracepoints), LSM, TC, XDP, Sockets ... | |
| | (BTF - 提供内核元数据, 增强钩子能力) | |
| +-------------------------------------------------------------------+ |
| |
+-----------------------------------------------------------------------------+
  • BCC (BPF Compiler Collection)

    • 构成: BCC 是一个强大的 eBPF 开发工具包和框架。其核心是一个 C++ 库,并提供了 Python、C++、Go 等多种语言的前端封装,其中 Python 前端最为流行和成熟。
    • 核心机制:
      • 运行时编译: BCC 的标志性特点是在程序运行时动态编译 eBPF C 代码。开发者在 Python 等脚本中嵌入 C 代码字符串,BCC 框架在后台调用 libclang (Clang 的库版本) 将其编译成 eBPF 字节码。
      • 自有的加载器: BCC 拥有一套自研的加载器逻辑,负责处理字节码的加载、Map 创建以及与内核的交互。
    • 与 libbpf 的关系:
      • BCC 诞生早于 libbpf 的成熟期,因此其核心不依赖 libbpf
      • 然而,为了拥抱社区标准和利用 CO-RE 等现代特性,新版本的 BCC 已经开始逐步集成 libbpf,并提供基于 libbpf 的新工具和 API。
  • libbpf

    • 构成: libbpf 是一个由内核社区维护的、用于开发 eBPF 应用的纯 C 语言核心库。它被认为是构建现代、高性能、可移植 eBPF 程序的事实标准
    • 核心机制:
      • 预编译 (Ahead-of-Time): libbpf 的典型工作流是在开发阶段就将 eBPF C 代码(.bpf.c)编译成包含字节码的 ELF 对象文件(.bpf.o)。
      • 智能加载: 用户态程序通过调用 libbpf 的 API,可以智能地解析 .o 文件,并将 eBPF 程序和 Maps 加载到内核。
      • CO-RE (一次编译,到处运行): 这是 libbpf王牌特性。它利用 BTF (BPF Type Format) 元数据,在加载时动态调整 eBPF 程序,以解决因内核版本不同导致的数据结构差异问题,极大地增强了程序的可移植性。
  • bpftrace

    • 定位与构成: bpftrace 是一款专为 Linux 设计的高级动态追踪语言和命令行工具。它的语法简洁强大,类似 awkDTrace,让使用者能用极少的代码快速排查系统性能问题。
    • 核心机制:
      • 高级语言到 C 的翻译: bpftrace 的核心是一个C++ 程序,它负责将用户编写的高级脚本实时翻译成 eBPF C 代码。
      • 后端依赖: 它不直接与内核交互,而是依赖一个后端引擎来完成编译和加载。
    • 与 libbpf/BCC 的关系:
      • 历史与现在: 早期 bpftrace 依赖 BCC 作为其后端。为了追求更好的性能、更轻的依赖和 CO-RE 支持,现代版本的 bpftrace 已经默认切换到使用 libbpf 作为其核心后端

对比表格:libbpf vs BCC vs bpftrace

特性 libbpf BCC bpftrace
定位 核心库 (Core Library) 开发框架 (Framework) 高级工具/语言 (High-level Tool)
主要用途 生产级应用、Agent、底层开发 快速原型、教学、脚本化开发 实时排障、命令行即时查询
编程接口 C/C++ API Python/C++ API 专用脚本语言 (类 awk)
编译时机 预编译 (开发时) 运行时 运行时
CO-RE 可移植性 原生支持 (核心优势) 支持有限/较弱 通过 libbpf 后端获得支持
运行时依赖 极轻量 重量级 中量级
需要 libbpf.so? 否 (但正在集成) 是 (现代版本)
需要 Clang/LLVM?
需要内核头文件? (传统方式)
需要 Python?
部署产物 单个二进制文件 Python脚本 + 运行时环境 bpftrace 工具 + 运行时环境
性能 最高 (启动快,无运行时编译开销) 中等 (有运行时编译开销) 中高 (比BCC快,但仍有运行时开销)
灵活性 最高 (完全控制) (动态修改 C 代码方便) 中等 (受限于语言特性)
易用性 (最复杂,需手写 C) 中等 (Python 封装,较友好) 最高 (最简单,一行命令)
最适合场景 需要嵌入到其他程序中的长期监控Agent,如Cilium、Datadog Agent。 编写一次性的调试脚本,探索内核行为,快速验证想法。 系统管理员在服务器上快速定位一个具体问题,如”哪个进程在大量读写磁盘?”

libbpf, bcc和bpftrace的结构和关联分析

https://goko-son626.github.io/post/libbpf-bcc-and-bpftrace.html

作者

GoKo Mell

发布于

2025-03-02

更新于

2025-09-11

许可协议

评论

:D 一言句子获取中...