很多人认识 eBPF,先看到的是它的外层成果:Kubernetes 网络绕开旧数据包路径,低开销观测,运行时安全 hooks,还有那些能回答常规日志流水线漏掉问题的 tracing 工具。这份清单没错,只是会把 eBPF 讲成一包基础设施技巧。Brendan Gregg 的 "BPF: A New Type of Software" 有用,正因为它往下走了一层。他谈 BPF 时,重点少在功能清单,多在一种新的软件运行位置;这个位置会改变性能工程、生产调试和内核安全。[1]
官方 eBPF 文档用更正式的说法讲同一件事:eBPF 源自 Linux 内核,能在特权上下文里运行沙箱化程序,并在保留内核源码和传统内核模块之外扩展内核能力。[2] 看这场演讲时,可以把这句话一直放在旁边。eBPF 的重要性,来自它改写了操作系统周围的扩展线。内核运行时可以被观察,也可以被影响;程序进入那里之前,先要经过权限、验证、受限 helper APIs、maps,以及同 hook 绑定的规则。[2][3][4]
所以,这段视频的看法要从“它能 trace 这么多东西”往外移一点:为了让 tracing、filtering 和 steering 贴近内核发生,系统安排了多少步骤和约束,才让普通运维者免于变成内核模块作者。Gregg 是性能工程师,他的例子自然围绕延迟、火焰图和生产观测展开。[1][5] 放到 OSS 的范围里,课程更宽:eBPF 的力量来自能力和约束一起出现。
图片说明:封面图是一张真实的机架式服务器和网络设备照片,保留了物理现场感。eBPF 的承诺落在运行中的 Linux 系统身上:它们可以暴露并处理内核级事件,同时遵守严格的执行契约。[6]
Around 3:30, the important move is from packet filters to general instrumentation
Gregg 从旧 Berkeley Packet Filter 的谱系讲起,真正的转折在后面:现代 BPF 早已越过单纯数据包过滤器的范围。[1] Cilium 参考指南把这段历史说得很清楚:classic BPF 常通过 packet filtering 和 tcpdump 为人所知,extended BPF 则在更新的 Linux 内核中变成一种更通用、更灵活、接近虚拟机的设施,用于 networking、tracing 和 security 等用途。[4]
这个变化容易被说轻。packet filter 原先是一种窄优化:把一小段程序放到网络流量旁,让用户空间少收无关数据。eBPF 把这个想法推成更大的内核运行模型。程序可以挂到 system calls、tracepoints、kernel probes、user probes 和 network events 等 hooks 上。[2] 结果是一套可复用的办法,把有明确限制的逻辑搬到事件发生的边上。
这里的重点是边界。工程师听到“在内核里运行自定义程序”就停住,eBPF 会显得莽撞。把路径走完,纪律就出来了:先选 hook,再编译成 bytecode,经由 BPF system call 加载,通过 verifier,调用被允许的 helpers,用 maps 交换状态,最后交给用户空间工具收集或引导结果。[2][3][4] Gregg 的演讲适合作为第一次观看材料,因为它让这条链路贴近实践,少了很多教科书式距离。[1]
Around 12:00, the verifier is the contract's center of gravity
视频里最重要的安全思想,核心在准入:程序只有在内核分析后确认可安全运行,才会被接纳。[1] eBPF Foundation 文档把 verification step 写成一道关口,用来检查权限,防止程序让系统崩溃或受损,并确认程序能运行到结束。[2] 文档随后列出更具体的限制:变量要初始化,内存访问需要边界检查,复杂度受控,循环也要有 verifier 能证明会退出的界限。[2]
这就是 eBPF 与随意 plug-in 模型之间的差别。普通扩展点常常在代码安装之后信任大量逻辑。传统内核模块权力极大,故障面也大。eBPF 把加载路径做成产品的一部分。程序先被编译,再在抵达 hook 前接受规则检查;这些规则先保护宿主机。[2][3]
这也解释了新用户为什么常被 eBPF 挫到。verifier 远远超出“错误信息更好的 linter”。它承担的是内核安全。某段程序在 C 程序员眼里很直观,只要 verifier 无法证明内存访问、循环边界或控制路径适合内核上下文,它仍会被拒绝。[2][3] 这篇文章给实践者的提示是:写 eBPF,需要把自己放进受限 runtime 里思考;拒绝加载代码,是这套系统的特性。
Around 20:00, maps make kernel work observable without turning the kernel into the app
注意到内核侧采集和用户空间呈现之间的分工后,Gregg 的性能示例会清楚很多。[1] eBPF maps 就是两侧之间的桥。eBPF 文档把 maps 描述成共享数据结构,程序和用户空间应用都能通过 system calls 访问它们,形态包括 hash tables、arrays、LRU structures、ring buffers、stack traces 和 longest-prefix-match tables 等。[2] 这是核心细节。它解释了 eBPF 工具为什么能在事件源附近收集事实,又把完整用户体验留在内核外面。
Brendan Gregg 自己的 eBPF tools 页面用性能案例展示了这个模式。一个自定义 eBPF 程序记录 block I/O timestamps,并把结果存进 histogram;用户空间程序定期读取 histogram,再画出 heat map。[5] 这种分工正是 eBPF 对可观测性有吸引力的地方。内核侧程序只在事件发生的一刻做最小且有用的工作。解释、渲染、聚合和操作员流程留在外面。[5]
对 OSS 基础设施来说,这是一条很有力的架构线。可观测性领域总会诱使系统收集更多原始数据,再把它们搬到别处。eBPF 提出的问题更尖锐:在事件边上先汇总出什么,才能让系统其余部分收到更小、更有意义的信号?traces、logs 和 metrics 仍然有用。eBPF 给团队增加了另一种提问方式;某些问题如果等所有事件先走完常规流水线,成本已经太高,时间也已经太晚。[1][5]
Around 30:00, helper calls are a compatibility boundary, not just a convenience API
eBPF 设计里有一个细节很关键:程序拿不到对内核内部的任意访问权。eBPF Foundation 文档说明,程序无法随便调用内核函数,因为那会把它们绑在特定内核版本上,也会让兼容性变复杂;它们改用内核提供的 helper functions。[2] Linux kernel documentation 的 BPF 部分把读者引向 verifier、syscall API、helper functions、program types、maps 以及相关设施的专门页面,也提醒我们,BPF 是一个有文档的子系统,靠口口相传无法概括它。[3]
这样看,helper calls 超出了便利包装的范围。它们是契约的一部分,让 eBPF 代码在靠近敏感内核状态时,仍保有足够实用的可移植性。helpers 暴露经过挑选的能力,例如 map access、time、random numbers、process 或 cgroup context,以及 packet manipulation。[2] 重要的是“挑选”。eBPF 强大,因为它贴近内核;它能稳定使用,因为这种贴近经过内核可以推理的 APIs 调解。
同一套契约也解释了高层工具和项目的重要性。许多用户会使用 bcc、bpftrace、Cilium、安全工具、profilers 或可观测性 agents,由这些工具封装底层办法。[2][4][5] 抽象尊重界限时,这是健康的。营销话术把 eBPF 说成无限制的内核魔法时,风险就出来了。更可靠的采用姿态,是弄清一个工具实际依赖哪些 hooks、helpers、maps、权限和内核版本。
Around 40:00, the OSS value is a shared substrate, not one vendor's feature
eBPF 值得进入 OSS feed,是因为它已经成为许多项目下面的共享基底。eBPF 文档明确点名 Cilium、bcc 和 bpftrace 等项目,把它们列为帮助用户在更高层工作、免于直接编写 bytecode 的抽象。[2] Cilium 指南把 BPF 放在 networking、tracing 和 security 之间讲,随后说明 Cilium 在自己的 data path 中大量使用 BPF,同时在读者需要细节时引向更底层的架构材料。[4]
这种分层就是开源故事本身。eBPF 让不同项目共享一种内核能力,再在上面竞争或专门化。网络项目可以用 BPF 引导数据包。tracing 工具可以用它采样 stacks 并汇总延迟。安全工具可以用它观察或约束运行时行为。共享基底不会让这些项目变成同一种东西,却会给它们一套共同词汇:hooks、maps、program types、helpers、verifier constraints 和 user-space loaders。[2][3][4][5]
风险在于,产品表面会把这套词汇盖住。团队如果只看 dashboard 或 Helm chart,就会错过真正决定 eBPF 适配度的运维问题:支持哪些 kernels?需要什么权限?程序被 verifier 拒绝时怎样处理?maps 里保留多少状态?哪些 events 被采样、汇总或丢弃?不同环境里的 hooks 有差异时,工具怎样降级?[2][3]
Gregg 的演讲至今仍有用,因为它训练观众从底层提问。[1] eBPF 远远超出“更快拿到图表”的范围。它是一套内核扩展契约:event-driven hooks、bytecode、verifier、helpers、maps、JIT compilation 和 user-space tooling 要一起成立。它们配合得当时,Linux 得到一层可编程的可观测性与控制平面,比“直接加载一个模块”安全得多,也比“以后再解析日志”更贴近事实发生处。[1][2][3][4][5]
来源
- Brendan Gregg, "Netflix talks about Extended BPF - A new software type," YouTube video, Ubuntu Masters, October 2019.
- eBPF Foundation, "What is eBPF?" - official introduction to hooks, verification, maps, helpers, JIT compilation, safety, and common project abstractions.
- The Linux Kernel documentation, "BPF Documentation" - kernel-side BPF documentation index for verifier, libbpf, syscall API, helper functions, program types, maps, testing, and related subsystem material.
- Cilium documentation, "BPF and XDP Reference Guide" - technical reference on BPF architecture, development tools, program types, and Cilium's use of BPF in its data path.
- Brendan Gregg, "Linux Extended BPF (eBPF) Tracing Tools" - practical performance-tool examples showing eBPF tracing, bcc, bpftrace, histograms, and user-space presentation.
- Wikimedia Commons, "File:Servers in a Rack.jpg" - source page for the real photographic cover image by Abigor.