本节摘要:eBPF 仍在获得新程序类型、更好的迭代器、硬件卸载和更强的调度/安全挂钩。扩张总是伴着更严的验证与更碎的内核版本现实。设计常驻系统时,把新能力分成“现在能用、探测后能用、只许写在路线图”。不要用博客上的未来图代替你节点上的 BTF。
阅读完本节,你应当能够:
第 1 章把 eBPF 定位成对模块方案的回答。回答会继续变长:更多挂钩、更多 Helper、甚至把程序卸到网卡。变长不等于你该全用。
现在能用: 你们生产内核矩阵里已经有、CI 已加载成功的程序类型。例如常见跟踪点、XDP、cgroup、libbpf CO-RE。
探测后能用: 新 Helper、fentry、某些 LSM、ringbuf。加载前查内核特性,没有则关功能,而不是让整个守护进程失败。
只许路线图: 内核邮件列表里的新接口、特定网卡才有的卸载、其他操作系统上的实现。可以研究,不能写进故障处理的关键路径。
电网新装了一套相量测量。调度规程不能在全网装置齐之前,假设每个变电站都能实时上传。eBPF 新挂钩同理。
安全。 LSM 程序类型让策略下沉更真。边宽了,误杀成本也宽了。发布流程应严于观测程序。
可观测。 迭代器、结构化导出让控制面能遍历任务和连接。它们是巡检工具,不是热路径。
网络。 卸载把 XDP 搬到硬件。性能跳变,调试跳变,语义子集跳变。开发机通过不等于 ASIC 上行为一致。
调度与资源。 更多 cgroup 与压力通知挂钩,让混部策略有机会下沉。仍要防第 5.2 节的合法饿死。
语言与测试。 Rust 前端、用户态模拟执行,让单元测试成为可能。模拟过不等于验证器过,两套测试都要。
跨操作系统。 其他内核上的 eBPF 兼容层在推进。对多数 Linux 生产集群,这是新闻不是依赖。API 看起来像,挂钩集合往往不像。
| 方向 | 诱惑 | 实际约束 |
|---|---|---|
| 硬件卸载 | 线速、零主机 CPU | Helper 少、难调试、网卡绑定 |
| LSM 下沉 | 真拦截 | 误杀、权限、灰度 |
| 迭代器 | 上帝视角遍历 | 不适合热路径 |
| 用户态模拟测试 | 快速反馈 | 不能替代真内核验证 |
| 跨 OS | 一套程序管混合云 | 挂钩与 Helper 集合不一致 |
| 内核内推理/模型 | 实时决策神话 | 指令上限与确定性 |
⚠️ 常见坑:把“某版本合入”当成“发行版已提供”。云厂商内核、长期支持分支、回移植情况差三年是常态。
💡 关键直觉:能力扩张的节奏由验证器与发行版决定,不由你的需求文档决定。需求可以先行,加载必须探测。
架构图可以留空槽:将来在卸载路径放过滤。代码里空槽必须是探测分支,默认关闭。特性开关进 Map,用户态可改,内核可热关。这比发版时发现发行版没有该程序类型更体面。
对社区新接口保持阅读,但评审标准仍是:矩阵覆盖了吗,失败可见吗,卸得掉吗。三项缺一,就还是路线图。
不必。跟踪点、XDP、Map、验证器已经够解决第 1 章那类缺口。等的是新挂钩,不是整项技术。用现在能用的档解决今晚的 P99,比等待完美 ABI 更符合问题驱动。
在指令与确定性约束下,顶多是极浅的决策树。把模型当卖点写进内核路径,通常是把不可解释的延迟送进最难调试的位置。决策树能表达的策略,Map 查找往往更清楚。
设计评审里最常见的膨胀,是把刚合入上游的挂钩写成关键路径。拒绝它需要标准,不能靠品味。标准可以是:该挂钩是否出现在我们矩阵的每一档;失败时是否有降级;卸载是否与现有平台冲突;验证复杂度是否把程序拖进路径爆炸;安全影响是否从旁观变成拦截。五问里有一个答“不知道”,就留在路线图。
对硬件卸载再加两问:没有该网卡的节点怎么办;卸载后的 Helper 子集是否仍能表达策略。若答案是“没有该网卡就没有防护”,那防护不能只放在卸载路径。主机路径仍要有功能相同、更慢的实现,或明确这些节点不承担对外暴露。
对跨操作系统再加一问:挂钩集合交集有多大。若交集只剩下套接字过滤,而你真正要的是 LSM,那“一套程序管混合云”是幻灯片。不如两套程序共享用户态控制面和策略格式,内核侧各自实现。控制面统一比字节码统一现实。
把路线图能力做成季度回顾,而不是需求文档里的永久未来。半年没进矩阵的,从设计图上摘掉,避免新同事以为已经存在。存在的定义是:CI 绿、有所有者、有预算。博客文章不是存在。
保持好奇仍然值得。新挂钩可能正好填上第 1.3 节某个缺口的更稳瞬间。好奇的出口是探测分支和测试节点,不是把生产加载改成“试试这个”。问题驱动的意思是:缺口在,工具才进;工具新,不自动等于缺口在。
设计把刚合入上游的挂钩写成必成功加载。发行版没有,上线失败。五问标准之后,这类设计在评审被拦下:矩阵有没有、失败能否降级、是否变拦截、验证会不会炸、和平台冲不冲突。有一问答不知道,就留在路线图。
硬件卸载在有卡的节点很快,没卡的节点等于没防护。后来主机路径保留功能相同的慢实现,或把没卡节点移出暴露面。不能让拓扑里的偶然网卡型号决定安全是否存在。
跨 OS 统一字节码的幻灯片很好看。真正要的 LSM 在另一边不存在。最后改成控制面统一、内核侧各自实现。字节码统一是愿望,策略格式统一是工程。愿望不进关键路径。
矩阵有没有、失败能否降级、是否变成拦截、验证会不会炸、和平台冲不冲突。一问答不知道,不进必成功路径。没卡节点怎么办,卸载 Helper 子集还能否表达策略,两问不过就保留主机慢路径或缩小暴露面。跨 OS 看挂钩交集,交集不够就控制面统一、内核侧分实现。路线图季度回顾,半年没进矩阵的从设计图摘掉,避免新同事以为已经存在。存在等于 CI 绿、有所有者、有预算。博客不是存在。今晚的缺口用今晚能加载的钩子解。用未来挂钩解今晚,是把故障交给日历。日历不值班。值班的人需要现在能挂上的跟踪点。跟踪点不够炫,但够用。够用优先于炫。炫留给探测分支和测试节点。测试节点可以失败。生产加载不可以拿失败当探索。探索有 bcc。生产有门禁。门禁后面才是新能力。
新挂钩的文章读起来像义务。义务感会把探测项写进必成功路径。必成功路径失败时,整套观测下线。下线的夜晚,旧跟踪点其实仍够用。够用的东西被新东西绑死,是能力扩张最阴的副作用。副作用的解药是三档分类写进加载器,而不是写进年度规划的形容词。形容词会过时。加载器里的探测分支不会因为形容词过时就去加载不存在的程序类型。不存在就关功能。关功能比关进程更像成年人。成年人解决今晚的 P99,用今晚能挂上的点。明天的点留给明天的矩阵。矩阵绿了再升档。升档是仪式,不是心情。
\n\n## 课堂补充\n\n三档分类写进加载器。合入不是发行版。五问不过留路线图。没卡要有慢路径。巡检和拦截分开审。模拟代替不了真内核。交集不够就分实现。模型不如查找清楚。半年不动就摘图。今晚用今晚的钩子。默认关探测。够用优先于炫。\n\n\n\n## 生产验收条\n\n1. 围绕「能力边界还在往哪扩」,生产验收只认能关掉、能计数、能对账,不认口头保证。\n2. 围绕「能力边界还在往哪扩」,把所有者、版本、卸载方式写成清单三件套,缺一视为幽灵。\n3. 围绕「能力边界还在往哪扩」,对照实验必须能回答开关前后业务指标动了没有。\n4. 围绕「能力边界还在往哪扩」,失败要分类到验证、额度、挂载、未触发、丢失,禁止只丢一句笼统错误。\n5. 围绕「能力边界还在往哪扩」,热路径默认克制,阈值之后才出栈,出栈之前先证明钩子活着。\n6. 围绕「能力边界还在往哪扩」,和平台已有挂钩点冲突时先登记再加载,禁止手工抢挂。\n7. 围绕「能力边界还在往哪扩」,内核版本矩阵没跑绿就不能把功能写成必成功路径。\n8. 围绕「能力边界还在往哪扩」,回滚必须碰到内核对象,心跳停止才算撤回成功。\n\n## 要点速记
下一章把前面所有闸门收成生产动作:开销从哪来、日志怎么拆、灰度签名与回滚怎么走。