Skip to content

第一百二十五章:eBPF

问道期

涉及内核源码:

林小源在网络之海的深处发现了一座奇特的锻造厂——里面没有铁锤和铁砧,只有一台精密的机器,不断吐出微小的程序片段。

"这是什么地方?"

"eBPF 虚拟机。"一个清脆的声音回答。

林小源看到一个年轻的女工匠站在机器旁,手中拿着一块透明的晶片。晶片上刻着微小的指令——eBPF 字节码。

"我叫 Verifier。"女工匠说,"eBPF 程序的验证器。每个 eBPF 程序在运行之前,都必须经过我的检查。"

"检查什么?"

"安全性。"Verifier 把晶片放在显微镜下,"我会检查程序是否有无限循环、是否访问非法内存、是否有可能崩溃内核。只有通过验证的程序才能在内核中运行。"

林小源看着那台机器:"eBPF 是什么?"

"extended Berkeley Packet Filter。"Verifier 说,"它是在内核中运行的虚拟机——用户可以编写小程序,编译成 eBPF 字节码,加载到内核中执行。用于网络过滤、性能监控、安全审计。"

"在内核中运行用户代码?那不会很危险吗?"

"所以有我。"Verifier 微微一笑,"验证器保证安全——你不能写死循环,不能访问越界内存,不能调用不安全的函数。通过验证的程序,内核还会做 JIT 编译——把字节码翻译成机器码,性能接近原生代码。"

"eBPF 有什么用?"林小源问。

Verifier 带他走进锻造厂的另一个房间。墙上挂着各种 eBPF 程序的用途图。

"XDP——eXpress Data Path。"Verifier 指着第一张图,"在网卡驱动层处理数据包。数据包还没进入内核协议栈就被处理了——最快。用于 DDoS 防御、负载均衡。Facebook 用 XDP 处理每秒数百万的数据包。"

"比 iptables 快?"

"快得多。iptables 在 netfilter 钩子上工作——数据包已经进入了协议栈。XDP 在更早的位置——驱动层。而且 eBPF 程序是 JIT 编译的,iptables 规则是解释执行的。"

"TC 呢?"

"Traffic Control。"Verifier 指着第二张图,"流量控制——限速、包过滤、标记。和 XDP 类似,但在更晚的位置——数据包已经从驱动层上来了。"

"还有 kprobe 和 tracepoint。"Verifier 指着最后一张图,"跟踪——动态跟踪内核函数(kprobe),或者在内核预定义的跟踪点上挂载程序(tracepoint)。用于性能分析、故障排查。"

"maps 是什么?"林小源注意到墙角有一排排小格子,每个格子里都放着数据。

"eBPF maps。"Verifier 走过去,"内核和用户空间共享的数据结构。eBPF 程序在内核中运行,它需要存储状态——计数器、哈希表、数组。这些状态放在 maps 里,用户空间的程序也可以读写 maps。"

"那 bpftrace 和 BCC 呢?"

"工具。"Verifier 说,"bpftrace 是高级跟踪语言——一行脚本就能跟踪内核函数。BCC 是 Python 绑定——可以编写复杂的 eBPF 程序。libbpf 是 C 库——最底层的接口。"

林小源看着那台不断吐出程序的机器,忽然明白了——eBPF 是 Linux 内核中最强大的可编程机制。它让用户可以在不修改内核代码的情况下,扩展内核的功能。

"但要记住。"Verifier 的表情变得严肃,"eBPF 不是万能的。它有指令数限制——不能写太复杂的程序。它有验证器限制——不能做所有事情。但在这个限制内,它是最安全、最高效、最灵活的扩展方式。"

c
/*
 * eBPF 的概念:
 *
 * 1. 虚拟机
 *    在内核中运行的虚拟机
 *    执行 eBPF 字节码
 *    安全、高效
 *
 * 2. 程序类型
 *    XDP: 网络数据包过滤
 *    TC: 流量控制
 *    kprobe: 内核探针
 *    tracepoint: 跟踪点
 *
 * 3. maps
 *    内核和用户空间共享的数据结构
 *    用于存储状态
 *
 * 4. 工具
 *    bpftrace: 高级跟踪语言
 *    BCC: Python 绑定
 *    libbpf: C 库
 */

printf("=== eBPF — 内核中的可编程 ===\n\n");

printf("eBPF 的概念:\n\n");

printf("1. 虚拟机:\n");
printf("   在内核中运行的虚拟机\n");
printf("   执行 eBPF 字节码\n");
printf("   安全、高效\n\n");

printf("2. 程序类型:\n");
printf("   XDP: 网络数据包过滤\n");
printf("   TC: 流量控制\n");
printf("   kprobe: 内核探针\n");
printf("   tracepoint: 跟踪点\n\n");

printf("3. maps:\n");
printf("   内核和用户空间共享的数据\n");
printf("   用于存储状态\n\n");

printf("--- eBPF 网络应用 ---\n");
printf("XDP (eXpress Data Path):\n");
printf("   在网卡驱动层处理数据包\n");
printf("   最快的网络处理\n");
printf("   用于 DDoS 防御\n\n");
printf("TC (Traffic Control):\n");
printf("   流量控制\n");
printf("   包过滤、限速\n\n");

printf("--- eBPF 跟踪 ---\n");
printf("kprobe:\n");
printf("   动态跟踪内核函数\n");
printf("   可以在任意内核函数上挂载\n\n");
printf("tracepoint:\n");
printf("   静态跟踪点\n");
printf("   内核预定义的跟踪位置\n\n");

printf("--- eBPF 工具 ---\n");
printf("bpftrace:\n");
printf("   高级跟踪语言\n");
printf("   一行脚本就能跟踪\n\n");
printf("BCC:\n");
printf("   Python 绑定\n");
printf("   编写复杂的 eBPF 程序\n\n");

printf("--- eBPF 的优势 ---\n");
printf("安全: 验证器检查程序\n");
printf("高效: JIT 编译\n");
printf("灵活: 可编程\n");

道藏笔记

内核启示

eBPF 在内核中运行用户定义的程序。

eBPF 的概念:

  • 虚拟机 — 在内核中执行字节码
  • 程序类型 — XDP、TC、kprobe、tracepoint
  • maps — 内核和用户空间共享数据

eBPF 网络应用:

  • XDP — 网卡驱动层处理,最快
  • TC — 流量控制

eBPF 跟踪:

  • kprobe — 动态跟踪内核函数
  • tracepoint — 静态跟踪点

eBPF 是"内核中的可编程"——安全、高效、灵活。


破关试炼

eBPF 之试

eBPF 让用户可在内核中运行受限程序,本章底层仍称它为什么程序体系?

答对后才能继续滑动和进入下一章。

以修仙之名,悟内核之道