eBPF 可观测性实战:从 kprobe 到用户态追踪的全链路监控体系
1. eBPF 可观测性概述
eBPF(extended Berkeley Packet Filter)是 Linux 内核中的一项革命性技术,它允许在内核空间中安全地运行沙箱程序,无需修改内核代码或加载内核模块。eBPF 已成为现代可观测性、安全和网络领域的基石技术。
1.1 为什么需要 eBPF?
传统的 Linux 可观测性工具(如 strace、tcpdump、systemtap)往往存在性能开销大、使用门槛高、需要重新编译内核等问题。eBPF 的核心优势包括:
- 安全性:eBPF 程序在执行前必须通过内核验证器(verifier)的严格检查,确保不会导致内核崩溃或死循环
- 高性能:JIT 编译为本地指令,执行效率接近原生内核代码
- 无需重新编译内核:可以在运行时动态加载和卸载
- 丰富的数据源:可以挂载到内核的任何函数、 tracepoint、perf 事件,甚至用户态函数
- 安全性高:verifier 确保程序不会访问未授权的内存地址
2. eBPF 探针机制
eBPF 提供了多种探针机制,从不同层次捕获系统行为数据。
2.1 kprobe/kretprobe — 内核函数动态追踪
kprobe 可以动态地在内核函数的入口点插入探针,kretprobe 则在函数返回时触发。这使得我们可以观测任何内核函数的调用情况,包括参数和返回值。
// kprobe 示例:追踪 do_sys_openat2 函数
SEC("kprobe/do_sys_openat2")
int trace_do_sys_openat2(struct pt_regs *ctx) {
struct file *filp = (struct file *)PT_REGS_PARM1(ctx);
bpf_printk("file opened: %s", filp->f_path.dentry->d_name.name);
return 0;
}
2.2 tracepoint — 内核静态追踪点
tracepoint 是内核开发者在关键代码路径上预先埋入的稳定追踪点。与 kprobe 相比,tracepoint 的 ABI 更加稳定,不会因内核版本变化而失效。
// Tracepoint 示例:追踪 sched_process_exec 事件
SEC("tracepoint/sched/sched_process_exec")
int trace_sched_process_exec(struct trace_event_raw_sched_process_exec *ctx) {
u32 pid = bpf_get_current_pid_tgid() >> 32;
char comm[16];
bpf_get_current_comm(

发表评论 取消回复