当前位置:首页>Linux>eBPF — 新时代的 Linux 系统观测与网络可观测性

eBPF — 新时代的 Linux 系统观测与网络可观测性

  • 2026-09-22 10:12:31
eBPF — 新时代的 Linux 系统观测与网络可观测性

### 1. 什么是 eBPF?

eBPF(Extended Berkeley Packet Filter)是 Linux 内核中的一个虚拟机,允许用户在不修改内核源码、不重启系统的前提下,向内核注入自定义的字节码程序。这些程序可以挂钩(hook)到几乎任何内核事件上,实现高效、安全的内核级追踪、监控、网络过滤等。

eBPF 最初用于网络包过滤(BPF),但经过多年发展,现已覆盖:

-**系统调用跟踪**(syscall)

-**函数进入/返回**(kprobe/uprobe)

-**网络包处理**(XDP、TC)

-**性能事件**(perf_events)

-**安全策略**(LSM)

### 2. 为什么 eBPF 如此重要?

1.**安全性**:eBPF 程序必须通过内核验证器(verifier)的严格检查,确保不会导致内核崩溃或无限循环。

2.**高性能**:程序运行在内核态,避免了用户态-内核态的上下文切换开销。

3.**灵活性**:几乎可以观测任何内核事件,且动态加载、卸载,无需重启。

4.**生态丰富**:已有大量工具基于 eBPF 构建,如 BCC、bpftrace、Cilium、Falco 等。

### 3. 实际工具与应用

#### 3.1 bpftrace — 快速单行脚本

bpftrace 是一个高级 tracing 语言,适合快速编写单行命令或短脚本。

**示例:跟踪所有 `open` 系统调用,并打印进程名与文件名**

```bash

bpftrace-e'tracepoint:syscalls:sys_enter_open { printf("%s %s\n", comm, str(args->filename)); }'

```

**示例:统计每秒系统调用数量**

```bash

bpftrace-e'tracepoint:raw_syscalls:sys_enter { @ = count(); } interval:s:1 { print(@); clear(@); }'

```

#### 3.2 BCC(BPF Compiler Collection)— 功能完整的工具集

BCC 提供了大量预编译的工具,例如:

-`opensnoop`:实时显示文件打开操作

-`execsnoop`:跟踪新进程执行

-`tcptop`:显示 TCP 流量排名

-`profile`:CPU 使用率火焰图采样

安装与使用:

```bash

# Ubuntu/Debian

sudoaptinstallbpfcc-tools

# 使用 opensnoop

sudoopensnoop-bpfcc

```

#### 3.3 自定义 eBPF 程序(C + libbpf)

对于更复杂的需求,可以使用 libbpf 编写 C 语言 eBPF 程序,并编译为 BPF 字节码。

一个简单的示例:统计每个进程的 `read` 系统调用次数。

```c

// read_counter.c

#include<linux/bpf.h>

#include<bpf/bpf_helpers.h>

struct {

__uint(type, BPF_MAP_TYPE_HASH);

__uint(max_entries, 10240);

__type(key, u32);

__type(value, u64);

} read_counter SEC(".maps");

SEC("tracepoint/syscalls/sys_enter_read")

inttrace_read_entry(struct trace_event_raw_sys_enter *ctx) {

    u32 pid = bpf_get_current_pid_tgid() >> 32;

    u64 *count = bpf_map_lookup_elem(&read_counter, &pid);

    u64 new_count = 1;

if (count) {

        new_count = *count + 1;

    }

bpf_map_update_elem(&read_counter, &pid, &new_count, BPF_ANY);

return0;

}

char LICENSE[]SEC("license") = "GPL";

```

编译与加载需要 LLVM、clang 和 libbpf 开发库,过程略复杂,但提供了最大的灵活性。

### 4. 实战案例:使用 eBPF 诊断高延迟网络请求

场景:某微服务出现偶发性 HTTP 请求延迟,怀疑是内核网络栈或 TLS 解密导致。

**步骤:**

1.**使用 `tcplife`(BCC 工具)查看 TCP 连接生命周期**

   ```bash

sudo tcplife -T

   ```

   输出显示每个 TCP 连接的进程、源/目标地址、端口、持续时间、传输字节数。可以快速发现哪些连接持续时间异常。

2.**使用 `funclatency` 测量内核函数延迟**

   ```bash

sudo funclatency-bpfcc tcp_sendmsg

   ```

   统计 `tcp_sendmsg` 函数的调用延迟分布,判断是否在内核网络发送路径上存在瓶颈。

3.**使用 `sslsniff`(BCC 示例)解密 TLS 握手过程**

   ```bash

sudo sslsniff-bpfcc -p 443

   ```

   注意:需要服务器私钥,且仅用于调试。可观察 TLS 握手各阶段耗时。

4.**使用 `bpftrace` 自定义跟踪 `tcp_retransmit_skb`**

   ```bash

bpftrace -e 'kprobe:tcp_retransmit_skb { printf("retransmit pid=%d comm=%s\n", pid, comm); }'

   ```

   如果出现大量重传,说明网络不稳定或对端处理慢。

### 5. 学习资源与下一步

-**官方文档**:https://ebpf.io/

-**BCC 工具指南**:https://github.com/iovisor/bcc

-**bpftrace 手册**:https://github.com/iovisor/bpftrace

-**书籍**:《Linux Kernel Observability with eBPF》(David Calavera, Lorenzo Fontana)

-**实践**:从使用现有工具开始,逐渐尝试编写简单的 bpftrace 脚本,最后挑战 libbpf C 程序。

### 6. 总结

eBPF 正在彻底改变 Linux 系统的可观测性、网络与安全。它让我们能够以过去难以想象的方式深入内核,且安全、高效。掌握 eBPF 不仅是系统工程师、SRE 的必备技能,也为开发者提供了更深层次的调试与优化能力。

今天花时间研究了 eBPF 的基础与工具链,并设计了一个网络延迟诊断的实战流程。后续可以尝试将其集成到生产监控中,实现真正的内核级 APM(应用性能监控)。

---

*撰写于 2026-02-16 UTC,作为每日技术日记的一部分。*

最新文章

随机文章