当前位置: 首页 > news >正文

eBPF 与 bpftrace:更深入地观测内核

eBPF 与 bpftrace:更深入地观测内核

实验环境:Ubuntu 24.04 / 内核 6.8.0-106-generic / Cgroup v2 / 华为云 FlexusX 8C16G
本文所有命令输出均来自真实实验机,可直接复现。bpftrace 版本 v0.20.2,内核自带 BTF。

一、引子:ftrace 还不够"聪明"的时候

上一篇 ftrace 能看调用链、能插桩内核函数,但它有个天花板:所有逻辑都在内核态"记录",聚合、过滤、统计得事后在用户态做。如果你想问"这个容器过去 10 秒里,每次read的延时分布是多少?"“哪个 cgroup 的openat最多?”“把几十万次事件按进程聚合出一张直方图”——ftrace 做不到在内核里就地算好再回传。

这时候需要eBPF:一套运行在内核态、带 JIT、有 Verifier 安全保障的虚拟机,让你写一小段 C 逻辑,挂到 kprobe / tracepoint / syscalls 上,在内核里直接聚合数据进 map,用户态只来取结果。再配上bpftrace(类 awk 的一行脚本语言),无需写 C、无需编译,就能把上面的问题一行搞定。


二、eBPF 原理简述

2.1 它是怎么跑起来的

  1. 写程序:用 C(BCC)或 bpftrace 脚本描述"探针触发时做什么"。
  2. 编译 + Verifier:LLVM 把 eBPF 字节码编译,内核Verifier在加载前做严格校验——无越界、无死循环、只访问合法内存、调用受限 helper——不通过就拒绝加载,因此 eBPF 不会把内核搞崩。
  3. JIT:校验通过后,eBPF 字节码被JIT 编译为原生机器码,执行开销接近普通内核代码。
  4. Map:eBPF 程序与用户态通过Map(内核里的键值存储,哈希表/数组/直方图等)交换数据。探针高频写 map,用户态低频读 map——这就是"内核态聚合"的关键。
  5. 挂载点:eBPF 程序可挂到kprobe / kretprobe(动态,同 ftrace 的 kprobe)、tracepoint(静态)、perf eventXDP(网络)、cgroup等。

2.2 它比 ftrace 强在哪

维度ftraceeBPF
聚合只能全量记录,事后分析内核态就地聚合(hist/sum/count)
过滤函数级 / 简单谓词任意 C 表达式谓词(comm==pid==、算数)
数据结构文本 trace 缓冲Map(直方图、统计、栈表)
编程能力无(配置式)图灵完备(可计算延时、关联事件)
安全内核内置,稳Verifier 沙箱保障
典型用途看调用链/耗时统计分布、按 cgroup 聚合、网络观测

一句话:ftrace 回答"发生了什么调用",eBPF 回答"这些调用按 X 维度聚合后长什么样"


三、bpftrace 单行实战

bpftrace 语法:probe { action },变量@name是全局 Map,退出时自动打印。下面每个都真跑过

3.1 系统调用次数 Top(谁最忙)

root@ecs-a8bb-0002:~# bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'Attaching1probe... @[wpa_supplicant]:1@[cron]:7@[timeout]:9@[sh]:109@[irqbalance]:102@[multipathd]:97@[pluginctl]:148@[bpftrace]:304@[remotectl]:348@[containerd]:929@[uniagentd]:3848

一眼看出本机系统调用最密集的是uniagentd(云监控 agent,3848 次)、containerd(929 次)。count()在 Map 里累加,退出时按值排序打印——这正是 eBPF "内核态聚合"的缩影。

3.2 跟踪 execve(execsnoop 效果)

execsnoop是经典工具:谁在偷偷起进程(可能是攻击、cron、 Hook)。bpftrace 一行复刻:

root@ecs-a8bb-0002:~# bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%-6d %-12s %s\n", pid, comm, str(args->filename)); }'Attaching1probe...49032bash/usr/bin/ls49033bash/usr/bin/whoami49034bash/usr/bin/sleep49035bash/usr/bin/grep49036bash/usr/bin/head

args->filename是 tracepoint 的上下文字段,str()把它从内核指针解成字符串。跑ls/whoami时被实时抓到——排查"未知进程从哪来"非常直接。

3.3 I/O 延时直方图

本来想做"块 I/O 延时直方图"(block:block_rq_issue/block_rq_complete算差值)。但本环境块设备走 virtio 半虚拟化,实测block:*tracepoint 完全不触发(已用count()验证block_rq_complete恒为 0)。这是云环境的真实限制,按"替代方案"原则,我换成VFS read 延时直方图——技法完全一样(入口记时间戳、出口算差值、丢进hist()),且必然可复现:

root@ecs-a8bb-0002:~# bpftrace -e 'tracepoint:syscalls:sys_enter_read{@start[pid]=nsecs;}tracepoint:syscalls:sys_exit_read /@start[pid]/{@us=hist((nsecs - @start[pid])/1000);delete(@start[pid]);}' @us:[0]190|@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[1]210|@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|[2,4)194|@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[4,8)20|@@@@@@[8,16)23|@@@@@@@[16,32)28|@@@@@@@@@[32,64)15|@@@@[128,256)11|@@@[256,512)5|@[512, 1K)1|[1K, 2K)8|@@[2K, 4K)1|[4K, 8K)3|

解读:绝大多数read0~4µs内完成(命中页缓存,极快);右侧长尾(ms 级)是首次读/页错误/落到磁盘的那几次。这正是直方图的价值——一眼看出"分布"而非只看平均值。同样的hist()+ issue/complete 时间戳差值技法,可直接套到块 I/O / 网络 / 任意两点间延时

3.4 跟踪容器内进程(按 comm 过滤)

要观测某个容器,在宿主机上用 eBPF 最方便的是按进程名(comm)过滤——容器的业务进程通常 comm 固定且不同于宿主。我编译了一个只做open/readiohog,放容器里跑(comm=iohog),宿主机上按 comm 过滤统计它的系统调用:

root@ecs-a8bb-0002:~# docker run -d -v /root/iohog:/iohog --name bpf-ct alpine /iohogroot@ecs-a8bb-0002:~# bpftrace -e 'tracepoint:syscalls:sys_enter_openat /comm=="iohog"/{@open=count();}tracepoint:syscalls:sys_enter_read /comm=="iohog"/{@read=count();}' @open:5787@read:11598

7 秒内,容器内iohog进程触发了 5787 次openat、11598 次read——完全隔离于宿主其他进程。如果把探针换成sys_enter_openat打印str(args->filename),就能逐条列出容器打开了哪些文件;换成sys_enter_accept4 /comm=="nginx"/就是经典的nginx 容器连接接受观测。这就是生产里"看清一个容器在干啥"的标准手法。

关于 cgroup 过滤:更精确的做法是按 cgroup id 过滤(bpftrace 有cgroup内建函数返回当前任务的 cgroup id)。本机 cgroup v2 目录无cgroup.id文件,但 cgroup id 等于该目录的 inode 号(stat -c %i /sys/fs/cgroup/.../docker-<id>.scope可取),用/ cgroup == <id> /即可精准锁定某容器。本实验用 comm 过滤已能干净隔离,故采用之。


四、BCC 与 bpftrace:怎么选

bpftraceBCC
形态单行/短脚本,类 awkPython + C,完整项目
上手极快,改一行就能跑需写 C 程序 + Python 胶水
能力覆盖 90% 观测场景任意复杂逻辑、自定义 Map、USDT、网络/XDP
依赖少(bpftrace + BTF)多(LLVM、Python、头文件)
典型临时排障、快速验证常驻监控、定制化工具、产品化

实践建议

  • 临时排查、验证假设:用bpftrace 一行脚本,5 秒出结果。
  • 要做成常驻监控 / 复杂关联(如按 cgroup 聚合所有容器的 TCP 重传):用BCC写工具,或基于 eBPF 的 Prometheus exporter(如cilium/ebpfbccTC/socket类)。
  • 容器场景:bpftrace 在宿主机跑,配合comm/cgroup/pid过滤观测任意容器,无需进容器。

五、排查思路:eBPF 在排障里的位置

  1. 先问"聚合后长啥样":延时分布(hist)、Top N(count)、速率(interval)这类问题,首选 eBPF/bpftrace。
  2. 容器观测范式:宿主机起 bpftrace → 用comm/cgroup/pid过滤器圈定目标容器 → 选 tracepoint(syscalls/sched/block 等)或 kprobe → 用 Map 聚合。
  3. 与 perf/ftrace 联动:perf 定位"CPU 热点函数" → ftrace 看"单次调用链与耗时" → eBPF 看"海量事件的分布与按维度聚合"。三者构成完整的核观测栈。
  4. 注意环境限制:如本机block:*tracepoint 不触发(半虚拟化存储)、部分 tracepoint 在容器视角的参数需str()解引用。遇到不触发就换同类探针(如块 I/O 改 VFS read),别卡死。

六、小结与思考题

小结:eBPF 是运行在内核态、经 Verifier 校验、JIT 执行的虚拟机,通过 Map 在"内核态聚合、用户态取数",比 ftrace 更适合统计分布与多维过滤。bpftrace 用一行脚本即可完成系统调用 Top、execsnoop、延时直方图、按 comm 过滤观测容器等任务。本环境实测block:*不触发,以 VFS read 延时直方图替代,技法一致。BCC 适合复杂/常驻场景,bpftrace 适合临时排障。

思考题

  1. eBPF 的 Verifier 为什么要禁止"无界循环"?如果允许,会有什么后果?
  2. 上面 read 延时直方图里,为什么大部分在 0~4µs,却有 ms 级长尾?(提示:页缓存命中 vs 页错误/磁盘)
  3. 要统计"每个 cgroup 的 TCP 重传次数",bpftrace 该挂哪个探针、用什么 Map?
  4. 为什么用comm过滤容器不如用cgroup过滤精确?什么情况下 comm 过滤会误伤或漏掉?
  5. block:block_rq_complete在本机恒为 0,这能说明"磁盘没有 I/O"吗?为什么?

(内核调试工具专题完。perf / ftrace / eBPF 三件套,分别对应"热点占比 / 调用链耗时 / 内核态聚合"三层观测能力,配合使用可覆盖绝大多数内核态排障场景。)

http://www.jsqmd.com/news/1261764/

相关文章:

  • 基于3D ResNet的平扫CT智能诊断系统设计与优化
  • 如何在普通PC上安装macOS:OpenCore黑苹果完整实战指南
  • 紧急更新!iOS/Android底层API变更导致73%番茄AI应用失效,附3行代码热修复方案与兼容性迁移清单(限时48小时)
  • 2026年郑州靠谱的电子无尘车间供货厂家选购全指南 - 品牌优推
  • 2026年7月长三角放电针优选南通锐锋钨钼,品质靠谱 - 起跑123
  • EDMA控制器寄存器深度解析:从PID到错误处理实战指南
  • taotoken多模型聚合平台为matlab数据分析提供ai增强方案
  • 告别手动配置烦恼:TEKLauncher如何让方舟游戏管理变得轻松有趣
  • 2026满城区高品质幼儿园TOP5测评:如何选择专业蒙氏教育与托育服务 - 中国品牌价值观察网
  • 工业自动化电机选型实战指南:从需求分析到参数计算与避坑
  • 人脸识别在校园考勤系统的应用与优化
  • Python+AI公考宝典:智能备考小程序开发实践
  • 跨平台音频下载工具:高效获取喜马拉雅有声内容完整方案
  • 成人业余中专(电大中专)2026年报名入口 - 湖北成人升学提升
  • WorkBuddy:用自然语言查询数据库,告别SQL取数烦恼
  • 10 和为k的子数组
  • 对比直接使用官方 API,通过 Taotoken 聚合调用的延迟体感差异
  • 谷歌下重手!Chrome浏览器迎来“大洗牌”,你的隐私终于有人管了?
  • 泉盛UV-K5/K6对讲机终极改造指南:解锁专业通信的完整教程
  • 终极指南:如何快速获取国家中小学智慧教育平台的电子教材资源
  • AI应用产品化阶段如何利用Taotoken实现模型选型与成本优化
  • 认识容器:从一个 nginx 容器看透 Namespace 与 Cgroup
  • KV Cache Offloading优化LLM推理显存占用
  • 2026每逢下雨屋内渗水怎么办?黄山顶楼、外墙漏水根治技巧 - 宅安选房屋修缮
  • 羽毛球学习 HarmonyOS 设计续篇(25):搜索列表性能与回到顶部策略
  • 内容创作团队如何借助Taotoken调用不同风格模型生成多样化文案
  • AI Agent实战:从零构建生产级智能体的完整指南
  • ComfyUI-WanVideoWrapper高级配置与性能优化实战指南
  • Win32 C++集成librdkafka实战:从编译到生产消费完整指南
  • 告别英文恐惧!3分钟让Figma说中文,设计师的母语工作流指南