eBPF 可观测工具怎样减少内核改动
我第一次把 eBPF 可观测工具接到一台不方便重编译内核的机器上时,最明显的变化不是多了一段内核代码,而是多了一个可以加载、验证、卸载的用户态观测程序。eBPF 的价值正在这里:把观测逻辑放在运行时加载的程序里,挂到内核已经提供的 tracepoint、kprobe 或 fentry/fexit 等位置,再通过 BPF Map 或 Ring Buffer 把摘要事件交给用户态。
官方资料:https://docs.ebpf.io/
eBPF 可观测工具减少的是“为采集数据而修改、编译、安装内核源码”的工作量,不是把内核接口变成永远稳定,也不是完全不需要内核能力。真正的判断标准是:观测目标是否已有合适挂载点,加载程序是否通过 verifier,以及目标内核是否提供所需的 BTF、权限和接口。
- 源码改动少:观测程序由用户态 loader 运行时加载,不必为每个指标新增一套内核模块。
- 数据路径清楚:内核侧只做必要的采集和聚合,用户态负责展示、存储和告警。
- 兼容性有边界:CO-RE 可以降低结构体布局差异的适配成本,但挂载点和 kfunc 仍需要版本与能力判断。
先把“少改内核”拆成三个动作
传统做法往往是改内核源码、重新编译或安装模块,再把采集逻辑放进修改后的路径。eBPF 把这个过程拆开:用户态 Loader 负责加载 ELF 对象;内核 verifier 检查程序是否满足安全规则;通过检查后,程序附着到已有的内核事件或函数入口。Linux tracing 文档把 tracepoint、ftrace、kprobe 等列为内核已有的追踪框架,这些位置就是 eBPF 可以借力的“接口面”。
这里的“已有”很重要。eBPF 不是凭空创造事件,而是利用内核已经暴露的上下文和挂载点。观测需求如果能落到现有事件上,就可以把新增逻辑放在用户态可管理的 BPF 对象里;如果根本没有合适事件,仍可能需要内核侧增加 tracepoint 或调整现有实现。

为什么观测逻辑可以放在内核源码之外
eBPF 程序不像普通内核模块那样拥有任意调用权限。它通常由用户态程序加载,经过 verifier 检查后才能运行;程序能访问什么上下文、能调用哪些 helper,也由程序类型决定。对观测工具来说,这个约束反而形成了清晰边界:内核侧负责在事件发生时读取少量字段、做必要过滤或聚合,用户态再把结果变成指标、日志或追踪数据。
BPF Map 是两侧的共享数据结构,Ring Buffer 则适合把事件记录送回用户态。下面的伪代码只展示数据职责,不绑定某个工具或内核版本。
struct event {
__u32 pid;
__u64 latency_ns;
};
// 中文注释:内核侧只提交必要字段,避免把大块上下文复制到用户态。
static __always_inline int record_event(struct event *e)
{
// 中文注释:真实程序还需按挂载点和 verifier 允许的访问方式取值。
return bpf_ringbuf_output(&events, e, sizeof(*e), 0);
}
// 中文注释:用户态负责读取事件、聚合指标并写入观测系统。
void consume_events(void) {
// 中文注释:此处代表 libbpf 或其他 loader 的 Ring Buffer 消费循环。
}
这段结构带来的收益不是“所有工作都在内核外完成”,而是让内核侧新增逻辑保持小而受限。采样比例、字段映射、存储格式和告警规则可以在用户态迭代,通常不需要重新编译内核。
tracepoint、kprobe 和 fentry 应该怎么理解
选择挂载点时,我会先问“我需要的是稳定事件,还是某个具体函数的细节”。tracepoint 是内核代码中预先定义的事件接口,适合围绕明确事件采集;kprobe 可以探测许多内核函数位置,但内核官方文档和 BPF 设计问答都提醒,kprobe 的挂载位置属于内部实现细节,函数变化后可能需要调整。fentry/fexit 使用 BPF trampoline 进入函数入口或返回点,能提供函数参数和返回值等更直接的观测上下文。
| 目标 | 优先考虑 | 需要留意 |
|---|---|---|
| 围绕内核已定义事件采集 | Tracepoint | 事件字段与版本支持仍需对照目标内核 |
| 快速观察某个函数 | Kprobe/Kretprobe | 函数名、参数和挂载位置不是稳定 ABI |
| 需要函数入口或返回值 | Fentry/Fexit | 依赖 BTF、内核能力与程序类型支持 |
因此,eBPF 减少的是“为获得观测点而改内核”的成本,不是让所有挂载点都拥有长期兼容承诺。文章标题中的“减少”必须和接口选择同时理解。
CO-RE 解决的是适配成本,不是所有兼容性
不同内核版本的结构体可能改字段、改布局,直接依赖固定内核头文件的 eBPF 程序容易因此失配。CO-RE 的思路是:编译产物携带 BTF 类型信息与重定位描述,libbpf 加载时读取运行中内核的 BTF,再把程序访问的类型和字段调整到当前内核。这样,一份 eBPF ELF 对象可以更容易适配多个内核版本。

但不能把 CO-RE 当成万能兼容层。内核 BPF 设计问答明确区分了不同接口:BPF 指令、helper 及参数属于 ABI;tracepoint 和 kprobe 挂载位置不是稳定 ABI;kfunc 也有自己的生命周期和兼容性预期。eBPF 文档同样建议对 kfunc 做防御式处理,不能默认它在所有内核上都存在。
把“减少改动”落成一张采用清单
- 先找现成事件:优先检查目标内核的 tracepoint、BTF 和可用程序类型,确认观测目标是否有直接入口。
- 再选数据边界:只在内核侧采集定位问题所需字段,把聚合、采样策略和存储交给用户态。
- 使用 CO-RE:通过 BTF 与 libbpf 处理结构体布局差异,避免为每台机器维护一份固定头文件版本。
- 记录降级路径:当 fentry、kfunc 或某个 tracepoint 不可用时,明确回退到更稳定事件、减少字段或关闭该观测项。
- 控制权限与开销:根据程序类型准备所需能力,关注采样频率、Map/Ring Buffer 容量和事件丢失策略。
如果只是要统计系统调用、网络连接或进程生命周期,成熟工具通常已经把这些判断封装好;如果要观察内部函数,则应把内核版本、BTF 完整性和挂载点稳定性纳入发布清单。
常见误区
- 误区一:eBPF 等于修改内核。可观测程序通常是运行时加载的 BPF 对象,和直接改内核源码不是一回事。
- 误区二:CO-RE 让程序永远兼容。它主要降低类型和字段布局的适配成本,不能替换对挂载点、kfunc 和权限的检查。
- 误区三:kprobe 比 tracepoint 更通用就更适合生产。它能快速接近函数实现,但函数内部细节变化也会提高维护成本。
- 误区四:内核侧采集越多越好。事件越大、频率越高,Ring Buffer 压力和观测开销越明显,应先做字段收敛和采样。
相关问题
eBPF 工具完全不需要重新编译内核吗?
通常不需要为了每个观测指标重新编译内核,但前提是目标内核已经提供所需挂载点、BTF 和程序能力。缺少事件或能力时,仍需改变观测方案,极端情况下要补充内核支持。
为什么不直接使用 kprobe?
kprobe 适合快速观察函数,但挂载位置和函数原型属于内部实现细节。对长期运行的工具,应优先考虑稳定事件,或用 CO-RE、能力探测和回退路径降低维护风险。
CO-RE 和 BTF 的关系是什么?
BTF 提供运行中内核的类型与布局信息,CO-RE 利用这些信息完成重定位,libbpf 则在加载阶段应用适配结果。三者共同降低跨内核版本部署成本。
最后可以把答案压缩成一句话:eBPF 可观测工具把新增观测逻辑从内核源码、编译和安装流程中抽离出来,借助已有挂载点、受限程序模型、BPF 数据结构和 CO-RE 完成运行时适配;但是否稳定,仍取决于挂载点、BTF、权限和接口生命周期。
云原生供应链安全项目如何分工
- 上一篇
- 云原生供应链安全项目如何分工
- 下一篇
- SLSA provenance 怎样描述构建来源
-
- 科技周边 · 业界新闻 | 14分钟前 | github · kubernetes · Kubernetes 开源协作 SIG Docs kubernetes/website 文档贡献
- Kubernetes SIG 文档怎样参与贡献
- 357浏览 收藏
-
- 科技周边 · 业界新闻 | 17分钟前 | gitHub actions · 供应链安全 OpenSSF Scorecard 仓库治理 Branch-Protection Code-Review Token-Permissions
- Scorecard 检查项怎样辅助仓库治理
- 281浏览 收藏
-
- 科技周边 · 业界新闻 | 24分钟前 | 云原生 · 容器 · kubernetes · 业界新闻 · Kubernetes Job restartPolicy initContainers Pod生命周期 Sidecar容器
- Sidecar 容器生命周期变化解决什么部署问题
- 310浏览 收藏
-
- 科技周边 · 业界新闻 | 26分钟前 | 软件供应链 SLSA 构建证明 provenance buildDefinition runDetails
- SLSA provenance 怎样描述构建来源
- 373浏览 收藏
-
- 科技周边 · 业界新闻 | 31分钟前 | 云原生 · 供应链安全 ·
- 云原生供应链安全项目如何分工
- 255浏览 收藏
-
- 科技周边 · 业界新闻 | 33分钟前 | 云原生 · WebAssembly WASI WIT Wasm Component Model 组件组合
- Wasm Component Model 解决了什么接口复用问题
- 236浏览 收藏
-
- 科技周边 · 业界新闻 | 35分钟前 | Collector SpanID TraceID OpenTelemetry Logs 可观测性关联
- OpenTelemetry Logs 信号怎样与 traces 关联
- 446浏览 收藏
-
- 科技周边 · 业界新闻 | 37分钟前 |
- Gateway API 如何补足传统 Ingress 的路由表达
- 269浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 985次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 991次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 1112次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 1081次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 927次使用
-
- 蒙面演唱引争议,旺仔小乔被平台封禁
- 2025-08-08 501浏览
-
- openGauss向量驱动升级,RAC多写突破内核
- 2025-07-30 501浏览
-
- 安普瑞斯工厂放假,电芯供应受影响
- 2025-07-04 501浏览
-
- 农产品APP开发优势与功能全解析
- 2025-04-30 501浏览
-
- 开店省钱妙招,外卖系统同城配送运营攻略
- 2025-04-26 501浏览

