第一章:eBPF 简介

在过去的几年里,eBPF 已经从相对默默无闻变成了现代基础设施建设中最热门的技术领域之一。就我个人而言,自从看到 Thomas Graf 在 DockerCon 17 的黑带会议(Black Blet)1 上谈到 eBPF 时,我就对它的可能性感到兴奋。在云原生计算基金会(CNCF),我在技术监督委员会(TOC)的同事把 eBPF 作为我们预测 2021 年将会起飞的重点技术之一来关注。超过 2500 人报名参加了当年的 eBPF 峰会线上会议,世界上最先进的几家软件工程公司共同创建了 eBPF 基金会。显然,人们对这项技术有很大的兴趣。

在这个简短的报告中,我希望能给你一些启示,为什么人们对 eBPF 如此兴奋,以及它在现代计算环境中提供的工具能力。你会了解到 eBPF 是什么以及为什么它如此强大。还有一些代码实例,以使这种感觉更加具象化(但如果你愿意,你可以跳过这些)。

你将了解到在建立支持 eBPF 的工具时涉及的内容,以及为什么 eBPF 在如此短的时间内变得如普遍。

在这份简短的报告中,难免无法了解所有的细节,但如果你想更深入地了解,我将给你一些参考信息。

扩展的伯克利数据包过滤器

让我们把缩写说出来:eBPF 代表扩展的伯克利数据包过滤器(Extended Berkeley Packet Filter)。从这个名字中,你可以看到它的根源在于过滤网络数据包,而且最初的 论文 2 是在伯克利实验室(Lawrence Berkeley National Laboratory)写的。但是(在我看来)这个名字对于传达 eBPF 的真正力量并没有很大的帮助,因为"扩展" 版本可以实现比数据包过滤多得多的功能。最近,eBPF 被用作一个独立的名称,它所包含的内容比它的缩写更多。

那么,如果它不仅仅是包过滤,什么是 eBPF?eBPF 是一个框架,允许用户在操作系统的内核内加载和运行自定义程序。这意味着它可以扩展甚至修改内核的行为。

当 eBPF 程序被加载到内核中时,有一个验证器确保它是安全运行的,如果无法确认,则拒绝它。一旦加载,eBPF 程序需要被附加到一个事件上,这样,每当事件发生时,程序就会被触发。

eBPF 最初是为 Linux 开发的,这也是我在本报告中重点讨论的操作系统;但值得注意的是,截至本文写作时,微软正在 为 Windows 开发 eBPF 的实现

现在,广泛使用的 Linux 内核都支持 “扩展” 部分,eBPF 和 BPF 这两个术语现在基本上可以互换使用。

基于 eBPF 的工具

正如你在本报告中所看到的,动态改变内核行为的能力非常有用。传统上,如果我们想观察应用程序的行为,我们在应用程序中添加代码,以产生日志和追踪。eBPF 允许我们收集关于应用程序行为的定制信息,通过在内核中观察它,而不必修改应用程序。我们可以在这种可观测性的基础上创建 eBPF 安全工具,从内核中检测甚至防止恶意活动。我们可以用 eBPF 创建强大的、高性能的网络功能,在内核内处理网络数据包,避免昂贵的用户空间转换。

从内核的角度来观测应用程序的概念并不新颖——这建立在较早的 Linux 功能之上,比如 perf 3,它也从内核内部收集行为和性能信息,而不需要修改被测量的应用程序。但是这些工具定义了可以收集的数据种类以及数据的格式。有了 eBPF,我们就有了更大的灵活性,因为我们可以编写完全自定义的程序,允许我们出于不同的目的建立广泛的工具。

eBPF 编程的能力异常强大,但也很复杂。对于我们大多数人来说,eBPF 的效用不是来自于自己写的程序,而是来自于使用别人创造的工具。有越来越多的项目和供应商在 eBPF 平台上创建了新一代的工具,包括可观测性、安全性、网络等。

我将在本报告后面讨论这些更高级别的工具,但是,如果你对 Linux 命令行很熟悉,迫不及待地想看到 eBPF 的运行,推荐你从 BCC 项目开始。BCC 包含丰富的追踪工具集合;即使只是瞥一眼列表也可以领略到 eBPF 广泛的应用,包括文件操作、内存使用、CPU 统计,甚至观察在系统任意位置输入的 bash 命令。

在下一章,我们将介绍改变内核行为的作用,为什么使用 eBPF 比直接编写内核代码更容易操作。

参考


  1. Thomas Graf,《Cilium——使用 BPF 和 XDP 的网络和应用安全》(DockerCon 2017 年 4 月 17-20 日) ↩︎

  2. Steven McCanne 和 Van Jacobson,《BSD 数据包过滤器:用户级数据包捕获的新架构》(工作文件,劳伦斯伯克利国家实验室,伯克利,1992 年 12 月 19 日)。 ↩︎

  3. perf 是一个 Linux 子系统,用于收集性能数据。 ↩︎