eBPF 全面介绍:从 Linux 内核机制到可观测性、网络、安全与 AIOps
从运维、SRE、Kubernetes 和 AIOps 的视角来看,eBPF 是非常值得深入学习的一项技术。它的重要性不只是“可以抓包”或者“可以监控系统调用”,而是因为它实际上给 Linux 内核提供了一种安全、动态、可编程的扩展机制:可以在不修改内核源码、不重新编译内核、通常也不需要编写传统内核模块的情况下,把自己的逻辑挂载到内核中的特定执行路径上。Linux 内核会在程序加载前使用 verifier 验证这些程序是否满足安全约束。(Linux Kernel 文档)
从运维、SRE 与云原生视角,可以概括为:
eBPF 的核心价值,是能够在“事件真正发生的地方”观察、统计甚至控制系统行为。
Prometheus 通常是在系统已经产生某个指标之后进行周期性采集,而 eBPF 可以进入系统调用、网络协议栈、调度器、文件系统、进程生命周期等内核路径,在事件发生时直接采集信息。正是这种能力,使 eBPF 成为现代 Linux 可观测性、云原生网络和运行时安全的重要底层技术。
1. 先理解传统 Linux 运维为什么需要 eBPF
假设线上出现一个问题:
某个 Kubernetes Pod API 延迟突然升高
通常会按照下面的路径排查:
Prometheus
↓
发现 API P99 延迟升高
↓
Grafana
↓
发现 CPU / IO / Network 指标异常
↓
kubectl logs
↓
应用日志
↓
strace / tcpdump / perf / ss / iostat
↓
逐步缩小问题
这些工具都很好,但它们存在一个共同问题:
不同工具只能看到系统中的某一层。
例如:
| 工具 | 主要观察层 |
|---|---|
| Prometheus | 指标 |
| Grafana | 指标展示 |
| logs | 应用事件 |
strace | 系统调用 |
tcpdump | 网络包 |
perf | CPU / 性能事件 |
ss | socket |
iostat | 块设备 |
/proc | 内核统计 |
如果问题发生在这样的路径上:
Application
↓
glibc
↓
syscall
↓
Linux kernel
↓
TCP/IP
↓
NIC driver
↓
Network
传统监控工具往往只能看到:
CPU = 80%
IOPS = 30000
latency = 300ms
但真正需要判断的是:
哪个进程?
哪个 Pod?
调用了哪个 syscall?
访问了哪个文件?
连接了哪个 IP?
哪个 TCP connection?
在哪个内核函数耗时?
哪个磁盘请求慢?
eBPF 就是在解决这个问题。
2. eBPF 本质上是什么
eBPF 可以理解为 Linux 内核中的一个受限制的虚拟执行环境。
从架构角度看:
User Space
┌───────────────────┐
│ eBPF Application │
│ Go / C / Rust ... │
└─────────┬─────────┘
│
│ bpf() syscall / libbpf
↓
┌──────────────────────────────────────────┐
│ Linux Kernel │
│ │
│ ┌───────────────┐ │
│ │ BPF Verifier │ │
│ └───────┬───────┘ │
│ │ │
│ ↓ │
│ ┌───────────────┐ │
│ │ eBPF Program │ │
│ └───────┬───────┘ │
│ │ │
│ ├── syscall │
│ ├── scheduler │
│ ├── TCP/IP │
│ ├── filesystem │
│ ├── cgroup │
│ ├── process │
│ └── device driver │
│ │
│ ┌───────────────┐ │
│ │ BPF Maps │ │
│ └───────┬───────┘ │
└───────────┼──────────────────────────────┘
│
↓
User Space
整个工作过程大致为:
编写 eBPF 程序
↓
编译
↓
eBPF bytecode
↓
加载进 Linux kernel
↓
Verifier 验证
↓
JIT 编译成本机机器码
↓
Attach 到某个 Hook
↓
事件发生
↓
执行 eBPF 程序
↓
写入 BPF Map / Ring Buffer
↓
用户态程序读取
↓
日志 / Prometheus / Grafana / AI 分析
不同 eBPF program type 能做什么,取决于程序挂载的位置及对应内核接口;内核 verifier 会根据程序类型限制允许访问的数据和 helper。(eBPF 文档)
3. eBPF 最重要的概念:Hook
eBPF 不是一个长期运行的普通 Linux 进程。
它更接近:
WHEN something happens
RUN this eBPF program
也就是:
事件
↓
Hook
↓
eBPF Program
例如:
进程执行
↓
execve syscall
↓
eBPF
↓
记录 PID / UID / command
或者:
TCP packet
↓
XDP
↓
eBPF
↓
DROP / PASS / REDIRECT
这也是理解 eBPF 最重要的一点:
eBPF 是事件驱动的内核程序。
4. eBPF 可以挂在哪里
这是整个 eBPF 技术体系最核心的部分。
4.1. Tracepoint
Linux 内核本身预先定义了很多 tracing point。
例如:
syscalls:sys_enter_openat
syscalls:sys_enter_execve
sched:sched_switch
sched:sched_process_exec
block:block_rq_issue
tcp:tcp_retransmit_skb
可以理解成 Linux 开发者预留的“观察接口”。
例如:
应用
↓
execve()
↓
Linux syscall
↓
tracepoint
↓
eBPF program
Tracepoint 的优点是接口相对稳定,因此非常适合作为生产环境 tracing 的入口。eBPF 有专门的 tracepoint program type 可以挂载到这些预定义内核 tracepoint。(eBPF 文档)
5. kprobe
如果内核没有提供需要的 tracepoint,就可以使用:
kprobe
kretprobe
它们可以挂载到 Linux kernel function。
例如:
tcp_v4_connect()
可以:
kprobe:tcp_v4_connect
这样每次内核调用:
tcp_v4_connect()
对应的 eBPF 程序都会执行。
比如:
process
↓
connect()
↓
tcp_v4_connect()
↓
kprobe
↓
eBPF
记录:
PID
process
src IP
dst IP
dst port
timestamp
因此就可以实现:
哪个进程
什么时候
连接了
哪个服务器
哪个端口
而不需要应用修改代码。Kprobe 本身不是 eBPF 特有功能,但 eBPF 可以通过相应 program type 与 kprobe 结合进行内核函数级 tracing。(eBPF 文档)
6. fentry / fexit
现代 eBPF tracing 越来越常使用:
fentry
fexit
它们可以理解成更现代的内核函数 tracing 方式。
例如:
tcp_v4_connect()
进入函数:
fentry
退出函数:
fexit
于是可以计算:
latency = exit_time - entry_time
例如:
start = now()
tcp_v4_connect()
end = now()
latency = end - start
这就是大量:
function latency tracing
工具的基本原理。
较新的 tracing program 可以利用 BPF trampoline,而不必完全依赖传统 kprobe 机制。(eBPF 文档)
7. uprobes:观察用户态程序
前面介绍的是:
kernel function
但如果想观察:
MySQL
Python
Redis
Nginx
JVM
就可以使用:
uprobe
uretprobe
例如:
mysqld
内部某个函数:
dispatch_command()
可以:
uprobe
↓
mysqld function
理论上就可以追踪:
MySQL 函数调用
latency
parameters
return value
同理:
Python interpreter
OpenSSL
glibc
Redis
Nginx
都可以进行用户态函数 tracing。
8. XDP:eBPF 最强大的网络能力之一
XDP 全称:
eXpress Data Path
普通 Linux 网络包路径大致为:
NIC
↓
Driver
↓
Linux network stack
↓
iptables
↓
TCP/IP
↓
socket
↓
Application
XDP 可以非常早地处理网络数据:
NIC
↓
Driver
↓
XDP eBPF
↓
Linux Network Stack
因此可以在一个网络包刚进入系统时决定:
PASS
DROP
REDIRECT
TX
例如:
Packet
↓
XDP
↓
if src_ip in blacklist:
DROP
else:
PASS
这就是为什么 eBPF 经常用于:
DDoS filtering
load balancing
packet filtering
network acceleration
XDP 还可以结合 devmap、cpumap 等 map 实现 packet redirect 等机制。Linux 官方文档明确将这些 map 与 XDP redirect 机制关联起来。(Linux Kernel 文档)
9. TC eBPF
除了 XDP,还有一个非常重要的网络位置:
Traffic Control
通常简称:
TC
例如:
NIC
↓
XDP
↓
Linux network stack
↓
TC ingress
↓
TCP/IP
↓
socket
或者出方向:
application
↓
socket
↓
TCP/IP
↓
TC egress
↓
NIC
TC 特别适合:
流量控制
网络策略
包修改
redirect
service routing
Cilium 等云原生网络系统大量利用类似的 Linux/eBPF datapath 能力。
10. cgroup eBPF
这对 Kubernetes 非常重要。
Linux container 的基础并不是所谓“容器内核”,而是:
namespace
+
cgroup
+
Linux kernel
因此 eBPF 可以挂载到 cgroup。
例如:
Pod
↓
container
↓
cgroup
↓
network connect
↓
eBPF
这时候就可以知道:
这个 connection 属于哪个 cgroup
进一步结合 Kubernetes metadata:
cgroup
↓
container ID
↓
Pod
↓
Namespace
↓
Deployment
于是:
10.42.2.8 → 10.42.3.9
这种传统网络信息,可以提升成:
namespace=order
pod=order-service-xxx
→
namespace=mysql
pod=mysql-primary
这就是 Kubernetes eBPF 网络可观测性的核心之一。
11. eBPF Program 到底长什么样
一个非常简化的 eBPF 程序可能类似:
SEC("tracepoint/syscalls/sys_enter_execve")
int trace_exec(struct trace_event_raw_sys_enter *ctx)
{
u32 pid = bpf_get_current_pid_tgid() >> 32;
bpf_printk("exec pid=%d\n", pid);
return 0;
}
含义非常简单:
当 execve syscall 发生
↓
获取 PID
↓
输出信息
可以将其理解为:
@on_execve
def trace_exec(event):
pid = get_pid()
print(pid)
只不过 Python 这段代码运行在用户空间,而 eBPF 程序会经过 verifier,并最终运行在内核受控执行环境。
12. Verifier:为什么 eBPF 可以进入内核
这是 eBPF 最关键的设计。
如果普通程序随便在内核中执行:
pointer error
memory corruption
infinite loop
kernel panic
整个操作系统都可能崩溃。
因此 eBPF 程序加载的时候必须经过:
BPF Verifier
其核心目标是证明:
这个程序可以安全执行
Verifier 会做程序控制流和数据流分析,并检查指针、内存访问、程序路径及程序类型约束等安全规则。(eBPF 文档)
可以把传统 kernel module 和 eBPF 粗略理解成:
Kernel Module
Developer
↓
"相信代码"
↓
Kernel
而 eBPF 更像:
Developer
↓
eBPF bytecode
↓
Verifier
↓
安全?
↓ ↓
YES NO
↓ ↓
Load Reject
这也是 eBPF 能够广泛用于动态观测和内核扩展的重要原因。
13. BPF Map:eBPF 最重要的数据结构
eBPF Program 本身适合处理事件,但通常还需要:
保存数据
统计数据
与用户空间通信
这就是:
BPF Map
例如:
key = PID
value = syscall_count
Map:
PID syscall count
1001 10034
1002 3844
1003 89342
程序:
syscall
↓
eBPF
↓
map[pid]++
用户空间:
Prometheus exporter
↓
read BPF Map
↓
metrics
BPF map 本身位于内核空间,既可以被 eBPF 程序访问,也可以被用户态程序访问,因此它们实际上构成了 eBPF 内核程序与用户空间之间最重要的数据交换和持久化机制之一。(eBPF 文档)
14. 常见 BPF Map
最容易理解的是:
HASH
ARRAY
PERCPU_HASH
PERCPU_ARRAY
LRU_HASH
例如监控 TCP connection:
BPF_HASH
key:
pid
src_ip
dst_ip
dst_port
value:
bytes
packets
latency
如果是高频事件,例如:
packet
syscall
scheduler
经常使用:
PERCPU_MAP
而不是所有 CPU 同时修改同一个 map。
原因是:
CPU0
CPU1
CPU2
CPU3
同时写一个 counter
会产生同步竞争。
Per-CPU map 变成:
CPU0 → counter0
CPU1 → counter1
CPU2 → counter2
CPU3 → counter3
最后用户空间:
sum(counter)
从而降低共享写竞争。Per-CPU map 是 Linux eBPF 中专门存在的一类 map。(eBPF 文档)
15. Ring Buffer:把事件送到用户空间
如果需要记录:
process exec
每次发生:
execve()
生成:
timestamp
pid
uid
command
就可以:
eBPF
↓
Ring Buffer
↓
User Space Program
例如:
15:31:01 pid=1032 bash
15:31:02 pid=1045 curl
15:31:03 pid=1056 python
因此可以把 eBPF 系统粗略理解成:
Hook
↓
BPF Program
↓
BPF Map / Ring Buffer
↓
User Space Agent
↓
Metrics / Logs / Events
16. Helper 与 kfunc
eBPF 不能像普通 C 程序一样随意调用 kernel function。
它主要通过内核提供的受控接口,例如 BPF helpers:
bpf_get_current_pid_tgid()
bpf_map_lookup_elem()
bpf_map_update_elem()
Linux 也逐渐提供:
BPF kfunc
即明确暴露给 BPF 程序使用的一部分内核函数。官方内核文档将 kfunc 描述为专门暴露给 BPF 程序使用的 kernel functions。(eBPF 文档)
所以:
eBPF
↓
Helper / kfunc
↓
Kernel capability
仍然处于明确限制中。
17. BTF 与 CO-RE
如果以后真正写 eBPF,这两个词一定会遇到:
BTF
CO-RE
BTF:
BPF Type Format
可以理解为:
Linux 内核数据结构的类型元信息。
例如内核有:
struct task_struct
不同内核版本:
5.15
6.1
6.6
...
结构字段和布局可能存在变化。
以前程序很容易产生:
kernel 5.x 可以运行
kernel 6.x 不能运行
现代 eBPF 采用:
CO-RE
Compile Once – Run Everywhere
结合 BTF,可以在不同内核版本中进行一定程度的结构适配。Linux 内核自己的 BPF Design Q&A 也明确建议使用 CO-RE,以降低不同 kernel version 内部数据结构变化造成的兼容问题。(Linux Kernel 文档)
这也是现在学习 eBPF 时应该优先理解的现代开发方式。
18. 为什么 Kubernetes 特别适合 eBPF
传统 Kubernetes 数据路径大致是:
Pod
↓
veth
↓
Linux network
↓
iptables / IPVS
↓
veth
↓
Pod
随着规模增大:
Service
NetworkPolicy
iptables rules
会变得越来越复杂。
而 eBPF 可以把部分逻辑直接程序化为:
packet
↓
eBPF
↓
Map lookup
↓
backend Pod
例如:
Service IP
10.96.0.10
↓
BPF map lookup
↓
10.42.1.3
10.42.2.7
10.42.4.12
这样网络数据面就变成了:
packet
↓
programmable datapath
↓
policy / load balancing / routing
而不是维护大量静态规则。
19. Cilium 就是非常典型的 eBPF 应用
Cilium 利用 eBPF 构建 Kubernetes networking/security datapath,而 Hubble 在其之上提供网络和安全可观测能力。官方文档将 Hubble 定义为构建在 Cilium/eBPF 之上的分布式 networking/security observability 平台。(Cilium 文档)
可以粗略理解为:
Kubernetes
↓
Cilium
↓
eBPF
↓
Linux Kernel
而:
Hubble
负责从这个 datapath 里把:
谁访问谁
请求是否被 drop
网络路径
L3/L4/L7 行为
表现出来。
20. eBPF 在运维与 SRE 中的应用
这里才是最值得关注的部分。
20.1. 系统调用监控
例如发现某个进程突然大量:
open()
read()
write()
connect()
可以统计:
Process syscall count
mysqld read 920134
mysqld write 321321
python connect 843
nginx accept 93434
这比:
CPU = 80%
深入得多。
21. 定位高 CPU
传统方法:
top
可能只能看到:
python 95%
eBPF profiling 可以继续分析:
Python
↓
function A
↓
function B
↓
function C
甚至结合 stack sampling 形成:
Flame Graph
于是问题从:
Python CPU 95%
变成:
80% CPU consumed by
function X
↓
JSON encode
↓
memory copy
这种能力对性能分析非常有价值。
22. 定位 IO 问题
例如:
MySQL replication lag
排查过程怀疑磁盘 I/O 存在异常。
Prometheus 只能看到:
disk latency
IOPS
util
eBPF 可以进一步 tracing:
process
↓
read/write syscall
↓
filesystem
↓
block layer
↓
device
于是可能得到:
mysqld pid=2341
write
size=128K
latency=120ms
device=nvme0n1
甚至进一步统计:
PID
container
IO size
IO latency
device
stack
此时定位问题的能力比只观察 iostat 高一个维度。
23. 定位 TCP 网络问题
例如:
API latency ↑
Prometheus:
HTTP P99 ↑
eBPF 可以继续追踪:
TCP connect latency
TCP retransmission
RTT
connection reset
packet drop
于是可以判断:
应用慢?
还是:
network RTT ↑
还是:
TCP retransmission ↑
还是:
packet drop ↑
这就是 eBPF 在网络 troubleshooting 中很重要的地方。
24. Kubernetes Pod 网络诊断
传统:
pod A
↓
service B
失败了。
此时可能需要:
kubectl exec
curl
nslookup
tcpdump
iptables
conntrack
如果采用 Cilium/Hubble 等 eBPF observability 能力,可以更直接地观察:
pod A
↓
TCP SYN
↓
NetworkPolicy
↓
DROP
甚至:
source:
namespace=order
pod=order-7832
destination:
namespace=payment
pod=payment-2341
port:
8080
verdict:
DROPPED
Hubble 的官方 CLI 文档就是围绕 inspecting network flows 设计的。(Cilium 文档)
25. 进程行为审计
例如,需要判断:
container
里面发生了什么。
可以监控:
exec
fork
open
connect
chmod
mount
例如:
Pod nginx
↓
/bin/bash
↓
curl 1.2.3.4
↓
chmod +x malware
这就是:
Runtime Security
领域。
Tetragon 就是典型案例,它利用 eBPF 进行 process execution、system call、network 和 file access 等安全观测,并支持 runtime enforcement。(GitHub)
26. 容器逃逸/异常行为检测
例如正常 nginx container 应该只是:
nginx
如果出现:
bash
curl
wget
nc
chmod
mount
eBPF 可以实时发现:
nginx
↓
execve("/bin/bash")
↓
eBPF event
↓
Security Agent
↓
Alert
再结合:
Pod
Namespace
Image
UID
Command
就可以形成:
Runtime security event
27. 数据库监控
在数据库资源池的运维场景中,eBPF 同样具有较高价值。
例如 MySQL:
mysqld
可以观察:
CPU
scheduler
disk IO
TCP
filesystem
syscall
因此可以做:
MySQL
↓
哪个实例?
↓
哪个 PID?
↓
IO latency?
↓
IO size?
↓
disk queue?
例如:
node
├ mysql instance A
├ mysql instance B
└ mysql instance C
Prometheus:
disk util = 95%
只能说明磁盘忙。
eBPF 则可以继续回答:
instance A → 10%
instance B → 75%
instance C → 15%
这对于共享数据库节点非常有价值。
28. 可以把 eBPF 与 Prometheus 结合
架构可以设计成:
Linux kernel
↓
eBPF
↓
BPF maps
↓
Agent
↓
Prometheus metrics
↓
Prometheus
↓
Grafana
例如 eBPF 统计:
TCP retransmits
IO latency
syscall latency
packet drop
然后 exporter:
GET /metrics
输出:
ebpf_tcp_retransmits_total
ebpf_io_latency_seconds
ebpf_tcp_connect_latency_seconds
ebpf_syscall_duration_seconds
再由 Prometheus 采集。
这样就形成:
kernel
↓
eBPF
↓
metrics
↓
Prometheus
↓
Grafana
这是非常典型的 eBPF observability pipeline。
29. eBPF 与 AIOps 的关系其实非常密切
这一点值得特别关注。
AI 做异常检测或者根因分析,最大的问题之一通常不是:
模型不够强
而是:
数据不够丰富
传统监控:
CPU
memory
disk
network
只有几十、几百种 metrics。
eBPF 可以产生:
process
syscall
TCP
DNS
HTTP
file
IO
scheduler
container
stack
这种更加细粒度的数据。
于是:
eBPF
↓
Telemetry
↓
Metrics / Events / Traces
↓
Feature Engineering
↓
Anomaly Detection
↓
Root Cause Analysis
例如发生:
API latency ↑
AI 不只是看到:
CPU ↑
而可以看到:
API latency ↑
↓
TCP retransmission ↑
↓
node eth0 packet drop ↑
↓
NIC queue saturation
这样的因果链显然更容易构建 RCA。
所以从 AIOps 的角度,可以把 eBPF 看成:
Linux 内核级 telemetry 数据源。
30. eBPF 生态中应当知道哪些工具
学习 eBPF 时不要一开始就自己写 C。
先学会使用成熟工具。
一个比较合理的层次是:
Level 1
使用 eBPF 工具
Level 2
理解 Hook / Map / Program
Level 3
用 bpftrace 写 tracing
Level 4
使用 BCC
Level 5
libbpf + CO-RE
Level 6
开发自己的 agent
30.1. 第一类:bpftrace
非常适合运维。
例如:
bpftrace -e '
tracepoint:syscalls:sys_enter_execve
{
printf("%d %s\n", pid, comm);
}'
可以将其理解为:
awk
+
DTrace
+
eBPF
非常适合:
临时故障排查
性能分析
事件追踪
31. BCC
BCC:
BPF Compiler Collection
提供大量现成工具。
例如常见思路包括:
exec tracing
TCP connection tracing
TCP retransmission tracing
block IO latency
filesystem latency
scheduler latency
学习阶段非常适合观察:
eBPF 到底能看到什么
而不需要立即解决 verifier、CO-RE、BTF 等开发问题。
32. libbpf
如果真正开发生产级 eBPF agent,目前比较重要的是:
libbpf
+
BTF
+
CO-RE
典型项目:
agent
├── xxx.bpf.c
├── xxx.h
└── userspace loader
其中:
xxx.bpf.c
运行:
kernel space
用户态:
C / Go / Rust
负责:
load
attach
read events
export metrics
CO-RE 也是 Linux 官方 BPF 文档推荐用于提高跨内核适应性的机制。(Linux Kernel 文档)
33. Go + eBPF
如果需要开发:
AIOps Agent
Monitoring Agent
Network Agent
Security Agent
建议重点关注:
Go
+
eBPF
架构非常自然:
eBPF C program
↓
Kernel
↓
Ring Buffer
↓
Go Agent
↓
Prometheus
↓
Kafka
↓
AIOps
Go 负责:
Agent lifecycle
HTTP
Prometheus metrics
Kubernetes API
Kafka
configuration
event processing
eBPF 负责:
kernel telemetry
二者职责分离非常清楚。
34. 从整个系统架构看 eBPF
最终可以形成:
Kubernetes
│
│ metadata
↓
Linux Kernel → eBPF Agent
│ │
│ ├ process
│ ├ syscall
│ ├ network
│ ├ IO
│ └ scheduler
│
↓
Ring Buffer / Maps
│
↓
Go Agent
│
├────────→ Prometheus
│
├────────→ Kafka
│
├────────→ Loki
│
└────────→ OpenTelemetry
│
↓
AIOps
│
↓
anomaly / RCA / alert
这实际上就是一个很有价值的 AIOps 数据采集 Agent 原型。
35. eBPF 入门项目设计
如果目标不只是学习语法,而是形成可落地的项目实践,则不建议从以下内容开始:
Hello eBPF
结束。
可以做一个:
35.1. Linux / Kubernetes eBPF Observability Agent
第一版只采集四类数据:
Process
Network
IO
System Call
例如:
Process
process_exec_total
process_exit_total
网络:
tcp_connect_total
tcp_retransmit_total
tcp_connect_latency
磁盘:
block_io_latency
block_io_size
系统调用:
syscall_count
syscall_latency
然后加入:
PID
process
container
Pod
namespace
node
metadata。
架构:
Linux Kernel
↓
eBPF
┌──────────┼───────────┐
↓ ↓ ↓
process network IO
│ │ │
└──────────┼───────────┘
↓
Ring Buffer
↓
Go Agent
↓
Prometheus
↓
Grafana
第二阶段:
Kafka
第三阶段:
Python
↓
Pandas
↓
anomaly detection
第四阶段:
AI RCA Agent
最终:
eBPF
↓
Telemetry
↓
Prometheus / Kafka
↓
Feature engineering
↓
Anomaly Detection
↓
LLM RCA
这会把 Linux、Kubernetes、Go/Python、Prometheus、数据分析和 AIOps 串成一个完整工程。
36. 几个非常重要的误区
36.1. eBPF 不是 Prometheus 的替代品
更准确的关系是:
eBPF
=
data collection / kernel telemetry
Prometheus
=
time-series monitoring system
二者可以组合。
36.2. eBPF 也不是 tcpdump 的简单升级版
tcpdump 主要围绕:
packet
而 eBPF 能观察:
network
process
syscall
IO
scheduler
filesystem
security
范围远大于网络抓包。
36.3. eBPF 也不是传统 kernel module 的完全替代
eBPF 有严格的 verifier、program type、helper/kfunc、execution context 和内核能力限制。它的价值正来自这种受约束的可编程性,而不是“可以在内核里执行任意代码”。(eBPF 文档)
37. 真正理解 eBPF,可以记住这张图
EVENT
│
┌─────────────────┼─────────────────┐
↓ ↓ ↓
syscall network scheduler
│ │ │
↓ ↓ ↓
Tracepoint XDP fentry
kprobe TC tracepoint
fentry cgroup
│ │ │
└─────────────────┼─────────────────┘
↓
eBPF Program
│
┌────────┴────────┐
↓ ↓
BPF Map Ring Buffer
│ │
└────────┬────────┘
↓
User Space
↓
Agent
┌──────────┼──────────┐
↓ ↓ ↓
Prometheus Logs Kafka
│ │
↓ ↓
Grafana AI
↓
Anomaly / RCA
理解该图后,即可建立对 eBPF 整体体系的基本认知。
38. 建议的学习顺序
不要先钻 eBPF 指令集或者 verifier 源码。对运维/SRE/AIOps 路线,更合理的顺序是:
- **先学 bpftrace。**亲自追踪
execve、TCP connect、TCP retransmit、block IO latency,建立“Linux 事件 → Hook → eBPF”的直觉。 - **补 Linux 内核路径。**重点掌握 process/syscall、scheduler、VFS、block IO、socket、TCP/IP、cgroup 与 namespace。否则会写 eBPF,但不知道应该 attach 在哪里。
- **理解 eBPF 核心机制。**重点是 Program Type、Attach Point、Verifier、Helper、Map、Ring Buffer、BTF、CO-RE。
- **学习 BCC 和现成工具。**重点不是背命令,而是研究“一个 CPU/IO/network 问题如何通过 eBPF 定位”。
- **再进入 libbpf/CO-RE 开发。**自己写一个小型 eBPF observability agent。
- **最后进入 Kubernetes。**研究 Cilium、Hubble、Tetragon 的设计,可以发现以前 Kubernetes 网络、监控、安全很多彼此分散的知识开始连接起来。Cilium/Hubble 和 Tetragon 都是当前非常典型的 eBPF 云原生工程案例。(Cilium 文档)
38.1. 从相关技术方向来看,eBPF 最值得学习的不是“会写几个 BPF 程序”
真正有价值的是形成这样一套能力:
Linux 内核
↓
理解事件发生的位置
↓
选择正确 Hook
↓
eBPF 采集
↓
Go Agent
↓
Prometheus / Kafka
↓
数据处理
↓
异常检测
↓
RCA
↓
AIOps
这样 eBPF 就不再是一项孤立技术,而会把 Linux、Kubernetes、网络、性能分析、Prometheus、Go/Python 和 AIOps 串起来。
实践阶段可以从 execve 进程追踪器开始:先使用 bpftrace 观察完整的 用户命令 → syscall → tracepoint → eBPF → 用户态输出 执行链,再逐步改造成基于 Go、eBPF 与 Prometheus 的 Linux/Kubernetes Observability Agent。这一路线比直接学习大量 eBPF API 更容易形成系统认知。
关联文档
- Linux 内核整体架构完整详解:理解 eBPF 所依赖的 Linux 内核执行环境。
- Linux 调试与追踪工具:对比 eBPF 与传统系统追踪、性能分析工具。
- 监控与可观测性:理解 eBPF 在现代可观测性体系中的定位。
