<!-- title: 内核里的JavaScript：eBPF如何重写Linux -->
<!-- domain: programming -->
<!-- video: https://www.youtube.com/watch?v=Wb_vD3XZYOA -->

# 内核里的JavaScript：eBPF如何重写 Linux

## 导语

如果你在过去十年用过 Kubernetes、刷过 facebook.com、或者被 Cloudflare 挡过一次 DDoS 攻击——你的数据包几乎可以肯定曾经穿过同一段代码：eBPF。Brendan Gregg 用一句近乎夸张的话来形容它——「**Linux 的超能力（superpowers for Linux）**」；他还有一个更精准、也更抓人的比喻：eBPF 就是**「把 JavaScript 塞进了 Linux 内核」**。

由 eBPF 基金会出品、Speakeasy Productions 制作的官方纪录片《eBPF: Unlocking the Kernel》（解锁内核）在 2023 年 KubeCon 北美站首映后，一直是系统编程圈子里被反复安利的「必看神片」。它讲的不是某个新框架的用法，而是一个更宏大的故事：**一群工程师如何把操作系统内核——这个地球上最稳定、也最难改变的东西——改造成一个可编程的平台**。

这部纪录片之所以值得每个程序员认真看一遍，是因为它揭示了一种我们平时很少思考的「平台进化论」：当一个系统的核心变得可以被安全地「编程」，它就不再是工具，而变成了生态。这篇文章，我们就借这部纪录片，把 eBPF 到底是什么、为什么重要、以及它正在如何悄悄重写整个云计算底层，一次讲透。

## 视频背景卡片

| 项目 | 内容 |
|------|------|
| 视频标题 | eBPF: Unlocking the Kernel [OFFICIAL DOCUMENTARY] |
| 频道 | eBPF Foundation（eBPF & Cilium Community） |
| 首映 | 2023 年 11 月，KubeCon North America |
| 时长 | 约 35 分钟 |
| 制作方 | Speakeasy Productions，eBPF Foundation / Isovalent 赞助 |
| 核心主题 | eBPF 技术的起源、社区历程与它对云原生生态的重塑 |
| 出镜先驱 | Alexei Starovoitov、Thomas Graf、Daniel Borkmann、Brendan Gregg、David S. Miller、Liz Rice |

## 核心内容拆解

### 一、一个绝佳的类比：内核版「JavaScript 时刻」

纪录片和官方文档都把同一个类比摆在最显眼的位置，而它确实是理解 eBPF 的最短路径。eBPF.io 的官方长文是这样开场的：回想 20 年前，网页几乎都是静态 HTML，浏览器只是一个「显示文档的应用」。今天呢？网页早已是完整的应用，浏览器本身几乎成了一台「独立的操作系统」。

这场进化的催化剂是什么？**是 JavaScript 带来的「可编程性（programmability）」**。有了 JS，开发者再也不用为了一个新功能去说服 W3C 加一个 HTML 标签、再等几年让所有用户升级浏览器。底层平台提供一组安全的「积木」，上层逻辑随时迭代——创新速度从此与浏览器版本解耦。

eBPF 做的是一模一样的事，只不过舞台从浏览器换成了 Linux 内核。内核的地位和当年的浏览器如出一辙：它是整个系统的「特权中枢」，最适合承载网络、安全、可观测性这些功能；但它同时又因为太关键、太需要稳定，创新速度慢得令人发指。改一行内核代码，要先说服 Linux 社区，再等几年新版本成为主流——纪录片反复强调的就是这个「**evolve too slowly**」的痛。eBPF 给出了一个全新的选项：**在运行时安全地向内核注入小程序，而不必改内核源码、也不必加载容易搞崩系统的内核模块（kernel module）**。

> 笔者注：这个类比是 eBPF 文献里最有传播力的一帧。它把一个冷冰冰的系统编程概念，翻译成了每个 Web 开发者都体验过的「平台革命」直觉。

### 二、从一个 1992 年的过滤器说起：BPF 的前世

要真正看懂纪录片的「起源篇」，得先把时间拨回 1992 年。Steven McCanne 和 Van Jacobson 在 BSD 上提出了 **Berkeley Packet Filter（BPF）**——一个用于抓包过滤的极简虚拟机。它的杀手锏是一个经典设计：两个 32 位寄存器 + 一个累加器，配合一套精简指令集。当年 `tcpdump` 之所以飞快，就是因为 BPF 把「要不要保留这个包」的判断直接做到了内核里，避免了把海量包拷到用户态。

这个老 BPF（后来被追称为 **cBPF，classic BPF**）安安静静地服役了二十年。真正的转折发生在 2014 年：**Alexei Starovoitov** 提交了一系列补丁，把内核里古老的 BPF 解释器彻底重写，扩展成今天的 **eBPF（extended BPF）**——10 个（后增至 11 个）64 位寄存器、新的调用指令、新的跳转语义。Wikipedia 的里程碑时间线清楚地记着：2014 年 3 月，网络栈主维护者 David S. Miller 接受了这次重构，随 Linux 3.18 发布。

有意思的是，正因为 eBPF 早已不再只是「包过滤器」，官方现在明确把它当作一个**不再展开的缩写（pseudo-acronym）**——就像 «LLM» 早就没人去念 «Large Language Model» 全称一样。纪录片里这些先驱的口吻，几乎都在讲同一个感受：**最初谁也没想到，一个抓包工具会长成改变操作系统架构的通用引擎。**

### 三、五步流水线：一段 C 代码如何「活」进内核

eBPF 之所以既能强大又能安全，靠的是一条精心设计的「加载流水线」。把它拆开看，你会惊叹于设计的周密：

1. **编写**：开发者用类 C 语言写程序（底层也支持直接写 bytecode，但很少这么做）。
2. **编译**：用 Clang/LLVM 把它编译成 eBPF 字节码。
3. **加载**：通过 `bpf()` 系统调用把字节码提交给内核。
4. **验证（Verification）**：内核里的 **verifier** 对字节码做静态分析。
5. **JIT 编译**：验证通过后，JIT 编译器把通用字节码翻译成本机机器码，跑起来和原生内核代码一样快。

整个过程是**事件驱动（event-driven）**的：程序不会主动循环执行，而是「挂」在某个 hook 点上——系统调用、函数进入/退出、内核 tracepoint、网络事件——一旦事件发生，内核就调用你的程序。如果预定义的 hook 不够用，还能用 **kprobe（内核探针）** 和 **uprobe（用户态探针）** 几乎挂到任何地方。

> 延伸分析：这条流水线最反常识的一点是「**验证在执行之前**」。绝大多数沙箱技术（如 V8 之于 JS、JVM 之于 Java）是「运行时限制 + 出错再杀」。eBPF 反其道而行——在程序还没跑之前，verifier 就用**抽象解释（abstract interpretation）**遍历所有可能的执行路径，确认它不会死循环、不会越界、一定能在有限时间内结束。这是一种「**证明安全，而非事后止损**」的范式。Linus Torvalds 本人在纪录片相关访谈里说：«BPF 的真正威力，在于它让人能写出『按需启用』的专用代码»。

### 四、Verifier：那个「最严面试官」，eBPF 安全的真正地基

纪录片把镜头给了一群先驱，但真正让 eBPF 能被 Linus 接受进内核的「无名英雄」，是 verifier。这部分内容，我建议你看完纪录片后一定要去翻 Wikipedia 和 BPF Internals 文档，因为它才是 eBPF 区别于「又一个内核模块」的根本。

verifier 检查的东西远比想象的多：程序是否保证**一定会终止**（无限循环、无限递归直接拒，后来才开放了有限的 «bounded loops»）；是否读了**未初始化的内存**；网络类程序是否访问了**包边界之外的内存**（防止偷看邻居的敏感数据）；是否**持有了没释放的自旋锁**（一次最多持一把，杜绝死锁）；复杂度是否在配置的上限之内——它会模拟每条指令、跟踪寄存器和栈的状态，一旦某条路径可能进入不安全状态，直接拒绝加载。

更妙的是它还有一层**加固（hardening）**：通过验证后，存放 eBPF 程序的内核内存会被设为只读，谁要是（因 bug 或被攻击）试图篡改它，内核宁可**直接崩溃**也不执行被污染的代码。它还针对 **Spectre** 这类侧信道攻击做了防护——对内存访问做掩码、跟随投机执行路径分析、JIT 层在无法转直调时发射 **retpoline**；所有常量都被做 **constant blinding**（常量致盲），防止攻击者把可执行代码伪装成常量（JIT spraying）。一句话：**eBPF 把「在内核里跑外部代码」这件原本极其危险的事，用一套工程化、可证明的安全机制管住了。**

> 笔者注：学术界甚至专门研究 verifier 本身的可靠性。2024 年 Springer 的一篇静态分析论文，就在挖 eBPF verifier 里潜在的 «unsound abstract operators»。这说明 eBPF 的安全模型已经被当作严肃的研究对象，而不只是工程技巧。

### 五、Maps、Tail Calls 与 CO-RE：让内核程序「可编程」的三件套

光能安全跑起来还不够，eBPF 之所以像 JavaScript 一样「可编程」，靠的是几样让程序能存状态、能组合、能移植的关键机制：

- **eBPF Maps**：内核里的高效键值存储。哈希表、数组、LRU、环形缓冲区（ring buffer）、栈回溯、最长前缀匹配（LPM）……程序用它和用户态交换数据、跨程序共享状态。这是 eBPF 从「无状态过滤器」进化为「有状态引擎」的关键。
- **Tail Calls（尾调用）**：一个 eBPF 程序可以跳去执行另一个程序并**替换执行上下文**，类似进程的 `execve()`。因为 eBPF 栈只有 512 字节，尾调用是「把复杂逻辑拆成多个小程序」、以及「不停机热更新」的核心手段。
- **CO-RE（Compile Once – Run Everywhere）**：这是现代 eBPF 最优雅的发明之一。eBPF 程序要用内核的内部数据结构，而不同内核版本里这些结构布局会变。CO-RE 靠 **BTF（BPF Type Format）**——一种比 DWARF 小约 100 倍的元数据格式——加上编译器生成的重定位信息，让 **libbpf** 能在加载时把程序「适配」到目标内核的结构布局。**一次编译，到处运行**，eBPF 终于拥有了 Java 般的可移植性。

纪录片着墨于人和故事，但这三件套才是 eBPF 从「极客玩具」走向「生产标配」的技术拐点。没有 CO-RE，eBPF 程序就得针对每一个内核版本单独编译——这在拥有上千个节点的云厂商那里是不可想象的。

### 六、三大战场：网络、可观测性、安全

纪录片的最后三分之一，几乎是在展示战利品。eBPF 今天已经吞下了云原生基础设施的三大核心战场：

**1. 网络。** 这是 eBPF 的起家之地。**XDP（eXpress Data Path）** 让 eBPF 程序挂在网卡驱动的收包最早期路径上，做包的极速处理和转发——它是 Linux 对用户态方案 DPDK 的回应，但**不绕开内核、与内核协同**。**Cilium** 把 eBPF 用到了 Kubernetes 网络上，**用 eBPF 数据面替换掉 kube-proxy 和 iptables**。要知道 iptables 在大规模集群下是出了名的「性能黑洞」，Cilium 的崛起直接改写了 CNI 格局，现在是 CNCF 生态里使用最广的 CNI 之一。

**2. 可观测性（Observability）。** Brendan Gregg 把 eBPF 称为超能力，主要指的就是这里。**bcc** 和 **bpftrace** 这套工具链，让你能以近乎零开销地看到内核和应用里发生的一切——哪个系统调用最慢、哪个函数在烧 CPU、网络在哪里丢包。Gregg 本人把 bpftrace 称为 **«DTrace 2.0 for Linux»**。Netflix 用它做全集群的网络可观测，LinkedIn、DoorDash 拿它做基础设施监控。

**3. 安全。** **BPF LSM** 让 Linux 安全模块可以被 eBPF 编程；**Falco** 用 eBPF 做容器运行时入侵检测（Shopify 在用）；Isovalent 的 **Tetragon** 做内核级的安全策略执行；Apple 用 eBPF 做 Kubernetes Pod 安全。Cloudflare 更是把 eBPF 用在了负载均衡、DDoS 防护和安全执行的全链路上。

> 延伸分析：仔细看 Wikipedia 那张超长的「采用方」清单，你会发现一个震撼的事实——**Meta 的四层负载均衡器 Katran，从 2017 年起处理了每一个发往 facebook.com 的数据包**；Google GKE、Cloudflare、Netflix、Apple、阿里巴巴、Walmart、纽约时报……几乎所有头部基础设施公司都在用。一部 35 分钟的纪录片背后，是 eBPF 已经事实上成为「云计算的隐藏操作系统层」。

### 七、纪录片的真正主角：那个「合并补丁」的社区故事

如果你只把这部纪录片当技术科普看，就错过了它最有价值的部分。Brendan Gregg 在自己博客里写了一段纪录片之外的私货，特别动人：2014 年 Alexei Starovoitov 来 Netflix 找他和 Amer Ather 聊 eBPF，三个人聊到忘了时间，被下一场会议的人「请」出了会议室，他才意识到连午饭都忘了吃。Alexei 当时信心满满，但隔几句就会补一句 **«if the patches get merged»（如果这些补丁能被合并的话）**。

这句话是整部纪录片的题眼。一个技术上「太好」的想法，要进 Linux 内核这种巨型代码库，靠的从来不只是代码质量，而是**策略、耐心、社区政治和一次又一次的重写**。纪录片把 2017 年 DockerCon 标记为「关键拐点」，把 2021 年 eBPF 基金会的成立标记为「社区承诺」，把 Isovalent 这家「模范 eBPF 创业公司」被 Cisco 收购标记为「商业验证」——它讲的其实是一个**开源技术如何从一个人的补丁，长成全行业地基**的故事。Gregg 在 2024 年的总结里说：**«十年过去了，eBPF 仍然像是刚起步»**——这句话既是谦逊，也是邀请。

## 知识结构图

```mermaid
flowchart TD
    A["类 C 源码"] -->|Clang / LLVM 编译| B["eBPF 字节码 bytecode"]
    B -->|bpf 系统调用 加载| C["Linux 内核"]
    C --> D{"Verifier 验证器<br/>抽象解释 / 静态分析"}
    D -->|拒绝: 死循环·越界·未初始化| X["❌ 加载失败"]
    D -->|通过| E["JIT 编译 → 原生机器码"]
    E --> F["事件驱动 Hook 点"]
    F --> F1["系统调用 / 函数进出"]
    F --> F2["kprobe / uprobe 探针"]
    F --> F3["网络: XDP / tc / socket"]
    F --> F4["tracepoint / LSM 安全"]

    F1 & F2 & F3 & F4 --> G["三大战场"]
    G --> G1["🌐 网络<br/>Cilium / XDP 替换 iptables"]
    G --> G2["👁 可观测性<br/>bcc / bpftrace / Hubble"]
    G --> G3["🔒 安全<br/>Falco / Tetragon / BPF LSM"]

    H["eBPF Maps 键值存储<br/>hash/array/ring buffer/LPM"] -.状态共享.-> F
    I["CO-RE + BTF<br/>一次编译 到处运行"] -.可移植性.-> E
    J["Tail Calls 尾调用<br/>程序组合与热更新"] -.组合.-> F

    K["核心类比"]:::meta
    K -.->|"把 JavaScript 塞进内核<br/>平台可编程性革命"| C

    classDef meta fill:#fff3cd,stroke:#d39e00,stroke-width:2px;
```

## 实战启示

**如果你是后端 / 云原生工程师**，eBPF 是未来五年最值得投入的方向之一，而且门槛正在快速降低。你不必从零写 verifier 认证的字节码——Cilium、Hubble、bpftrace、Falco、Pixie 这些上层项目，已经把 eBPF 封装成了「声明式」工具。最务实的上手路径是：先在测试集群里把 kube-proxy 换成 Cilium，感受一次 eBPF 数据面的网络性能与 Hubble 的流量可视化；再用 `bpftrace` 一行命令 (`bpftrace -e 'tracepoint:syscalls:sys_enter_* { @[probe] = count(); }'`) 体验「零改代码看穿系统」的震撼。

**如果你是性能 / SRE 工程师**，eBPF 等于给了你一台「全集群 X 光机」。Gregg 在纪录片里反复强调：eBPF 可观测性工具是**性能工具，不是安全工具**——别指望它直接防攻击，但用来定位延迟、丢包、CPU 热点，它是降维打击。值得读他的《BPF Performance Tools》和 Liz Rice 的《Learning eBPF》。

**如果你是架构师**，纪录片最该带走的洞察是**「平台可编程性」这个抽象**。当你发现自己公司的核心系统也在「evolve too slowly」——改一个能力要走漫长的发版流程——不妨想想：能不能像 eBPF 之于内核那样，在核心之上加一层**安全、可热加载、事件驱动的可编程扩展层**？WebAssembly、可编程网关、规则引擎，本质上都是同一思想在不同栈上的投影。eBPF 给出的工程答案——**先证明安全再执行（verifier）+ JIT + 一次编译到处运行（CO-RE）**——是任何想做「平台化」的团队都该抄作业的范本。

**最后，一句认知升级**：操作系统内核曾是我们「敬畏而不可触碰」的黑盒；eBPF 之后，它变成了一个**可被编程、可被观测、可被安全扩展的平台**。理解了这一点，你就理解了过去十年云计算底层静悄悄发生的那场革命。

## 延伸学习路径

1. **Liz Rice《Learning eBPF》(O'Reilly, 2023)** —— 当前最友好的入门书，从零写第一个 eBPF 程序。
2. **Brendan Gregg《BPF Performance Tools》(Addison-Wesley, 2019)** —— 880 页的性能观测圣经，纪录片主角之一的心血。
3. **eBPF.io 官方长文 «What is eBPF?»** —— 本文大量架构细节的来源，配图清晰，免费。
4. **Cilium 官方文档与 eCHO 系列视频** —— 想搞 Kubernetes 网络绕不开，eCHO 是 eBPF/Cilium 社区的常驻节目。
5. **IETF RFC 9669（2024 年 10 月发布）** —— eBPF 指令集架构（ISA）正式标准化，标志着 eBPF 从「Linux 专有」走向跨系统规范（含 Windows 移植）。

## 一句话总结

**eBPF 把「JavaScript 的可编程性」搬进了 Linux 内核，用 verifier + JIT + CO-RE 这套组合拳，让最难改变的操作系统核心变成了可安全热加载的可编程平台——它是过去十年云计算底层最沉默也最深远的一场革命。**

## 参考来源

1. [eBPF: Unlocking the Kernel [OFFICIAL DOCUMENTARY]](https://www.youtube.com/watch?v=Wb_vD3XZYOA) — 本文深度解读的核心视频
2. [What is eBPF? — eBPF.io 官方长文](https://ebpf.io/what-is-ebpf/) — 架构、verifier、maps、JS 类比的权威来源
4. [eBPF Documentary — Brendan Gregg 博客（2024-03-10）](https://www.brendangregg.com/blog/2024-03-10/ebpf-documentary.html) — 2014 Netflix 轶事与社区评论
5. [The eBPF Documentary - Unlocking the Kernel — eBPF.io Blog（2023-11-08）](https://ebpf.io/blog/2023/11/03/the-ebpf-documentary/) — 纪录片幕后、先驱名单与社区历程

---
> 本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵**爱卫生**（微信ID: gprshome201101）维护，聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。
> 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
