基于 BCC 的 eBPF 实操入门

💡 原文中文,约4000字,阅读约需10分钟。
📝

内容提要

eBPF是扩展伯克利包过滤的缩写,用于实现内核不支持的功能。它有多种开发工具,如BCC、libbpf-bootstrap和Cilium。文章介绍了一个使用eBPF的示例程序,并解释了加载进内核部分和用户空间部分的含义。同时,还介绍了一些bpf系统调用的示例。

🔎

延伸解读

BCC 的抽象与底层系统调用

BCC 提供了简洁的应用层接口,让开发者无需直接编写复杂的 bpf 系统调用。但文章通过 strace 示例揭示,BCC 最终仍是通过 bpf 系统调用与内核交互,例如 BPF_PROG_LOAD 加载程序、BPF_MAP_CREATE 创建映射。理解这一层有助于调试和性能分析,当 BCC 行为不符合预期时,可以追踪系统调用定位问题。

eBPF 程序的双重结构

示例程序明确分为加载进内核的部分和用户空间部分。内核部分通常用 C 编写,经编译后通过 bpf 系统调用加载;用户空间部分负责加载、附加和读取数据。这种分离意味着开发者需要同时关注内核态的安全限制和用户态的控制逻辑,两者通过 eBPF Maps 等机制通信。

eBPF Maps 的多样性与选型

eBPF Maps 不仅支持数组和哈希表,还针对特定操作优化,如 FIFO 队列、LIFO 栈、LRU 存储、最长前缀匹配和布隆过滤器。选型时需考虑键类型、操作模式和数据规模。例如数组映射固定使用 4 字节索引,而哈希表支持任意键类型。合理选择映射类型能提升程序效率。

从 kprobe 到实际观测

文章以 kprobe 为例,通过 attach_kprobe 将 eBPF 程序挂载到 execve 系统调用上,实现跟踪。这展示了 eBPF 的典型用途:读取系统调用和网络包信息。但需注意,eBPF 通常只允许读取,少数修改场景(如网络包)才被允许,这体现了内核的安全约束。

❓

Q&A

eBPF是什么,它的主要用途是什么?

eBPF是扩展伯克利包过滤的缩写,主要用于实现内核不支持的功能,通常用于读取系统信息,少数情况下允许修改信息。

有哪些常见的eBPF开发工具?

常见的eBPF开发工具包括BCC、libbpf-bootstrap和Cilium。

kprobe在eBPF中有什么作用?

kprobe是内核探针的关键名词,用于在内核中插入探针以监控特定事件。

eBPF Maps有哪些类型,它们的用途是什么?

eBPF Maps有多种类型,包括数组和哈希表,主要用于优化特定操作,如FIFO队列和哈希存储。

如何使用BCC加载eBPF程序?

使用BCC加载eBPF程序时,首先编写程序代码,然后通过BCC提供的接口将其加载到内核中。

bpf系统调用的函数原型是什么?

bpf系统调用的函数原型为int bpf(int cmd, union bpf_attr *attr, unsigned int size);

🏷️

标签

➡️

继续阅读