Linux eBPF、BCC 与 bpftrace 生产观测排障指南

传统监控告诉我们“CPU 高、磁盘慢、网络丢包”,eBPF 则可以在内核和用户态关键路径上动态观测函数、系统调用、调度、网络和 I/O,回答“是谁、在什么路径、因为什么变慢”。它能力强大,但错误探针、高频事件和不受控输出也可能增加生产负担。本文建立安全使用 eBPF/BCC/bpftrace 的排障方法。

eBPF 工具通常需要高权限,可看到进程、文件、网络和容器敏感信息。生产使用前必须获得授权,限制脚本来源、运行时间、输出内容与访问范围。任何探针都应先在测试环境验证。

一、eBPF 不是魔法

eBPF 程序在受限虚拟机模型下运行,加载前经过 Verifier 检查,再附着到 Tracepoint、kprobe、uprobes、LSM、网络 Hook 等位置。数据通过 Map、Ring Buffer 等机制传到用户空间。

事件发生(系统调用/调度/网络/函数)
  ↓
内核中的 eBPF 程序过滤与聚合
  ↓ Map / Ring Buffer
用户态工具读取、符号化和展示

它能降低“为一个问题重启应用加日志”的成本,但观察结果仍需要结合应用、内核版本和业务上下文解释。

二、工具选择

  • BCC:大量现成 Python/C 工具,适合快速诊断;
  • bpftrace:类似 awk 的追踪语言,适合临时脚本和聚合;
  • libbpf/CO-RE:适合长期运行、跨内核版本的工程化 Agent;
  • perf:CPU Profiling、硬件计数器和内核事件仍非常重要;
  • bpftool:检查已加载程序、Map、Link 和 BTF。

优先使用稳定 Tracepoint;kprobe 依赖内核函数实现,升级后可能变化。Uprobe 依赖二进制符号、优化和版本。

三、运行前安全基线

  1. 记录内核、发行版、架构和 BTF;
  2. 确认工具与内核兼容;
  3. 估算事件频率;
  4. 尽量在内核侧过滤和聚合;
  5. 设置运行时长与自动退出;
  6. 输出到独立磁盘或限速管道;
  7. 避免打印请求正文、密码、密钥和完整路径;
  8. 先观察再执行任何阻断型 eBPF 策略。

对 sys_enter 等高频全局事件逐条 printf,可能产生巨量输出和明显开销。

四、先用传统工具缩小范围

推荐顺序:

uptime
vmstat 1
mpstat -P ALL 1
pidstat -dur 1
iostat -xz 1
ss -s
sar -n DEV,TCP,ETCP 1

先判断 CPU、内存、磁盘、网络或锁,再选择 eBPF 工具。否则很容易收集大量数据却没有问题假设。

五、CPU 与 Off-CPU 分析

On-CPU 火焰图回答 CPU 时间花在哪里;Off-CPU 分析回答线程为何不在 CPU 上,例如等待 I/O、锁、调度或定时器。

BCC 常用:

profile-bpfcc -F 49 30
offcputime-bpfcc -df 30
runqlat-bpfcc 10
runqlen-bpfcc 10

采样频率不宜无上限提高。应用缺少符号、启用 Frame Pointer 省略或 JIT 时,栈可能不完整,需要 DWARF、JIT 符号或语言专用 Profiling 配合。

六、调度延迟

CPU 利用率不高但请求仍抖动,可能是 Run Queue、CPU 限额、优先级、NUMA 或宿主机 Steal。

观察:

  • Run Queue 延迟分布;
  • 每 CPU 队列长度;
  • 进程被唤醒到真正运行的时间;
  • Cgroup CPU Throttling;
  • 上下文切换和迁移;
  • IRQ/SoftIRQ 占用。

在容器中还要同时看宿主机与 Cgroup 指标,Pod CPU 使用低不代表没有被限流。

七、磁盘 I/O 延迟

常用工具:

biolatency-bpfcc 10
biotop-bpfcc 10
biosnoop-bpfcc 10
fileslower-bpfcc 10

区分应用发起到文件系统、块层排队、设备服务时间和文件系统回写。iostat await 是设备视角,应用等待可能还包含锁、Page Cache、Writeback 和 Sync。

生产应限制按进程/磁盘过滤。全盘逐 I/O 打印会造成大量数据。

八、文件系统与 Page Cache

排查缓存命中、慢文件操作、打开失败和 Sync:

cachestat-bpfcc 5
filetop-bpfcc 5
opensnoop-bpfcc -p <pid>
syncsnoop-bpfcc

文件路径可能包含敏感租户和业务信息,采集前必须脱敏。容器 OverlayFS 路径与容器内路径可能不同,需要结合 Mount Namespace 解释。

九、网络连接与 TCP

tcpconnect-bpfcc
tcpaccept-bpfcc
tcpretrans-bpfcc
tcpstates-bpfcc

可回答谁发起连接、到哪里、重传和状态变化。排障时结合:

  • SYN 重试与 Listen Queue;
  • TCP Retransmit;
  • RTT 与拥塞;
  • DNS 时间;
  • NAT/Conntrack;
  • CNI、Service 和 NetworkPolicy;
  • 网卡丢包和 SoftIRQ。

重传不一定是物理网络坏,也可能是接收端 CPU 忙、队列溢出或防火墙丢弃。

十、bpftrace 基础

列出可用探针:

bpftrace -l 'tracepoint:syscalls:sys_enter_openat'
bpftrace -lv 'tracepoint:syscalls:sys_enter_openat'

统计进程系统调用:

bpftrace -e '
tracepoint:raw_syscalls:sys_enter
{ @[comm] = count(); }
interval:s:10
{ print(@); clear(@); exit(); }'

生产脚本应有过滤、聚合和退出条件。Map 不清理可能持续增长;高基数 Key(PID + 路径 + 地址)尤其危险。

十一、延迟直方图

平均值会掩盖尾延迟。bpftrace 可在函数进入时记录时间,返回时计算分布,但需要为线程键清理 Map。

bpftrace -e '
kprobe:vfs_read { @start[tid] = nsecs; }
kretprobe:vfs_read /@start[tid]/ {
  @us = hist((nsecs - @start[tid]) / 1000);
  delete(@start[tid]);
}
interval:s:20 { print(@us); clear(@us); exit(); }'

内核函数名和签名可能随版本变化;示例使用前必须在目标内核验证。

十二、容器与 Kubernetes 归属

内核事件只看到 PID、Cgroup、Namespace 等,需要把它映射到 Pod、容器、Namespace 和工作负载。常见平台 Agent 会做上下文富化。

注意 PID Namespace:容器内 PID 1 在宿主机有不同 PID。排障脚本如果只按容器内 PID 过滤,可能抓不到目标。

十三、用户态 Uprobe

Uprobe 可跟踪应用函数、TLS 库、数据库客户端和语言运行时。但优化、内联、符号剥离和版本变化会影响准确性。

使用前确认:

  • 二进制完整路径与 Build ID;
  • 函数符号是否存在;
  • 参数 ABI 与架构;
  • 动态库实际加载位置;
  • 多进程/多容器实例;
  • 是否会采集敏感参数。

十四、Verifier 与加载失败

Verifier 检查终止性、指针访问、边界、Map 和帮助函数使用。加载失败时查看 Verifier Log,常见原因:

  • 越界访问;
  • 未初始化变量;
  • 指针类型不安全;
  • 循环与指令复杂度;
  • 内核不支持某 Helper/Map/Hook;
  • BTF 或 CO-RE 重定位失败。

不要通过换到宽松主机规避问题,应修正程序并记录兼容矩阵。

十五、性能开销评估

开销取决于事件频率、每次执行指令、Map 操作、栈采集和用户态输出。评估方法:

  1. 测量启用前业务基线;
  2. 在代表性负载启用最小探针;
  3. 观察 CPU、延迟、丢事件和 Map 内存;
  4. 逐步加入字段;
  5. 达到时限自动退出;
  6. 再次测量业务指标。

长期 Agent 应暴露自身 CPU、内存、丢事件、Ring Buffer 和加载失败指标。

十六、事件丢失与数据误读

Ring Buffer 满、用户态处理慢或采样可能导致事件丢失。诊断报告应明确:

  • 是否采样;
  • 是否有 Lost Event;
  • 采集窗口;
  • 过滤条件;
  • 内核与工具版本;
  • 数据是否代表全部请求。

没有这些信息的火焰图和统计不能直接作为根因证据。

十七、生产排障模板

  1. 写清现象、时间、影响和变更;
  2. 用指标确定资源方向;
  3. 提出可证伪假设;
  4. 选择最低开销探针;
  5. 限定进程、Cgroup、端口或设备;
  6. 运行固定时间并保存元数据;
  7. 将内核事件与 Trace/日志/业务指标关联;
  8. 停止探针并验证无残留;
  9. 形成根因、修复与防复发措施。

十八、监控与治理

组织应维护经评审的脚本库、内核兼容矩阵、审批流程、最大运行时间、敏感字段规范和应急停用方式。禁止随意从互联网下载 root 权限 eBPF 脚本在生产执行。

十九、常用场景速查

  • CPU 忙:profile、火焰图;
  • CPU 不忙但延迟高:offcputime、runqlat;
  • 磁盘慢:biolatency、biotop;
  • 文件慢:fileslower、opensnoop;
  • 网络重传:tcpretrans;
  • 短连接多:tcpconnect、tcpaccept;
  • 缓存异常:cachestat;
  • 系统调用异常:Tracepoint 聚合;
  • 应用函数慢:Uprobe + 延迟直方图。

参考资料

  • Linux Kernel BPF Documentation:https://docs.kernel.org/bpf/
  • bpftrace Documentation:https://bpftrace.org/docs/
  • BCC Repository and Tools:https://github.com/iovisor/bcc
  • libbpf Overview:https://libbpf.readthedocs.io/
Copyright © yan-jian.com 2023 - 2026 · Powered by GitBook更新时间: 2026-11-03 16:23:45

results matching ""

    No results matching ""