paint-brush
eBPF 如何改变我们所知道的可观察性🕵️‍♀️🐝经过@zerok
2,804 讀數
2,804 讀數

eBPF 如何改变我们所知道的可观察性🕵️‍♀️🐝

经过 ZeroK13m2023/05/28
Read on Terminal Reader

太長; 讀書

eBPF 是一个编程框架,它允许我们在 Linux 内核中安全地运行沙盒程序,而无需更改内核代码。 eBPF 程序在设计上非常高效和安全——它们经过内核验证,以确保它们不会危及操作系统的稳定性或安全性。它最初是为 Linux 开发的(今天仍然是技术最成熟的地方)
featured image - eBPF 如何改变我们所知道的可观察性🕵️‍♀️🐝
ZeroK HackerNoon profile picture
0-item
1-item

解码 eBPF 可观察性:

在过去的 2 年里,云原生社区中有很多关于 eBPF 的讨论。 eBPF 是 KubeCon 的中流砥柱eBPF 日eBPF 峰会越来越受欢迎,谷歌和 Netflix 等公司多年来一直在使用 eBPF ,并且新的用例一直在出现。特别是在可观察性方面,eBPF 有望成为游戏规则的改变者。


那么让我们看看 eBPF——什么是技术,它如何影响可观察性,它与现有的可观察性实践相比如何,以及未来会怎样?

eBPF 究竟是什么?

eBPF 是一个编程框架,它允许我们在 Linux 内核中安全地运行沙盒程序,而无需更改内核代码。


它最初是为 Linux 开发的(今天它仍然是技术最成熟的地方),但微软正在迅速发展Windows 的 eBPF 实现


eBPF 程序在设计上非常高效和安全——它们经过内核验证,以确保它们不会危及操作系统的稳定性或安全性。

那么为什么 eBPF 很重要呢?

要理解这一点,我们需要了解用户空间和内核空间。


用户空间是所有应用程序运行的地方。内核空间位于用户空间和物理硬件之间。用户空间中的应用程序不能直接访问硬件。相反,它们对内核进行系统调用,然后内核访问硬件。


所有内存访问、文件读/写和网络流量都经过内核。内核还管理并发进程。


基本上,一切都通过内核(见下图)。

eBPF 提供了一种安全可靠的方式来扩展内核功能。


用户空间和内核空间


从历史上看,由于显而易见的原因,更改内核源代码或操作系统层中的任何内容都非常困难。


Linux 内核有3000 万行代码,任何更改从一个想法到广泛可用都需要数年时间。首先,Linux 社区必须同意它。然后,它必须成为官方 Linux 版本的一部分。然后,几个月后,它被 Red Hat 和 Ubuntu 等发行版采用,将它带给更广泛的受众。


从技术上讲,可以将内核模块加载到自己的内核中并直接进行更改,但这是非常高的风险并且涉及复杂的内核级编程,因此几乎被普遍避免。


eBPF 出现并解决了这个问题 - 并提供了一种安全有效的机制来在内核中附加和运行程序。


让我们看看 eBPF 如何同时确保安全性和性能。

高度安全

  • 严格验证- 在任何 eBPF 程序加载到内核之前,它都会由eBPF 验证程序验证,这确保代码绝对安全 - 例如,没有硬循环、无效内存访问、不安全操作。


  • 沙箱- eBPF 程序在内核中的内存隔离沙箱中运行,与其他内核组件分开。这可以防止未经授权访问内核内存、数据结构和内核源代码。


  • 有限的操作——eBPF 程序通常必须用 C 语言的一小部分来编写——一个受限的指令集。这限制了 eBPF 程序可以执行的操作,从而降低了安全漏洞的风险。

高性能/轻量化

  • 作为本机机器代码运行——eBPF 程序在 CPU 上作为本机机器指令运行。这导致更快的执行和更好的性能。


  • 无上下文切换——常规应用程序定期在用户空间和内核空间之间进行上下文切换,这是资源密集型的。 eBPF 程序运行在内核层,可以直接访问内核数据结构和资源。


  • 事件驱动——eBPF 程序通常只在响应特定的内核事件时运行,而不是一直运行。这最大限度地减少了开销。


  • 针对硬件优化——eBPF 程序在执行前由内核的 JIT(即时)编译器编译成机器代码,因此代码针对其运行的特定硬件进行了优化。


因此 eBPF 为编程提供了一个安全高效的内核钩子。鉴于一切都通过内核,这开辟了几个直到现在才可能的新可能性。

为什么现在才这么重要?

围绕 eBPF 的技术已经发展了很长时间,并且已经发展了大约 30 年。


在过去的 7-8 年里,eBPF 已经被几家大公司大规模使用,现在我们正在进入一个使用 eBPF 成为主流的时代。观看Alexei Starovoitov 的这段视频,他是 Linux 的共同创造者和 eBPF 的共同维护者,介绍了 eBPF 的发展。

eBPF——简史

  • 1993 年 - 劳伦斯伯克利国家实验室的一篇论文探讨了使用内核代理进行数据包过滤。这就是 BPF(“Berkeley Packet Filter”)这个名字的由来。

  • 1997 - BPF 作为 Linux 内核(版本 2.1.75)的一部分被正式引入。

  • 1997-2014 - 添加了几个特性来改进、稳定和扩展 BPF 功能。

  • 2014 - 引入了一个重要的更新,称为“扩展的 Berkeley 数据包过滤器”(eBPF)。此版本对 BPF 技术进行了重大更改并使其更广泛地使用 - 因此使用了“扩展”一词


为什么这个版本很大,是因为这使得扩展内核功能变得容易

程序员可以或多或少地像编写常规应用程序一样编写代码——周围的 eBPF 基础设施负责低级验证、安全性和效率。

围绕 eBPF 的完整支持生态系统和脚手架使这成为可能(见下图)。

eBPF 生态系统和堆栈

资料来源:https: //ebpf.io/what-is-ebpf/

更好的是,eBPF 程序可以在不重启的情况下从内核加载和卸载。

所有这一切突然允许广泛采用和应用。

在生产系统中广泛采用

eBPF 的受欢迎程度在过去 7-8 年呈爆炸式增长,几家大公司在大规模生产系统中使用它。


  • 到 2016 年,Netflix 广泛使用 eBPF 进行跟踪。实施它的Brendan Gregg作为 eBPF 的权威在基础设施和运营界广为人知。

  • 2017 - Facebook 开源了他们基于 eBPF 的负载均衡器Katran 。自 2017 年以来,发往Facebook.com的每个数据包都通过了 eBPF。

  • 2020 年——谷歌将 eBPF 纳入其 Kubernetes 产品。 eBPF 现在为 GKE 的网络、安全和可观察性层提供支持。到目前为止,像Capital OneAdobe这样的公司也有广泛的企业采用。

  • 2021 - Facebook、谷歌、Netflix、微软和 Isovalent 共同宣布成立eBPF 基金会,以管理 eBPF 技术的发展。


现在有数千家公司在使用 eBPF,并且每年都会出现数百个 eBPF 项目,探索不同的用例。


eBPF 现在是 Linux 内核中的一个独立子系统,有广泛的社区支持它。该技术本身已经通过一些新增功能进行了相当大的扩展。

那么我们可以用 eBPF 做什么呢?

eBPF 最常见的用例在 3 个领域 -


  1. 联网
  2. 安全
  3. 可观察性


Cilum等项目的推动下,安全和网络得到了更广泛的采用和应用。相比之下,基于 eBPF 的可观察性产品的发展较早,才刚刚起步。


让我们先看看安全和网络方面的用例。

安全

安全性是 eBPF 的一个非常流行的用例。使用 eBPF,程序可以观察内核级别发生的一切,高速处理事件以检查意外行为,并比其他方式更快地发出警报。


例如 -


  • 谷歌使用 eBPF 进行大规模入侵检测

  • Shopify使用 eBPF 实现容器安全


一些第三方安全产品现在使用 eBPF 进行数据收集和监控。

联网

网络是另一个广泛应用的用例。在 eBPF 层允许全面的网络可观察性,例如对包括所有跃点在内的完整网络路径的可见性,以及源和目标 IP。使用 eBPF 程序,可以在内核中以非常低的开销直接处理大量网络事件和操作网络数据包。


这允许各种网络用例,如负载平衡、DDoS 预防、流量整形和服务质量 (QoS)。


可观察性

到现在为止,eBPF 如何在可观察性中发挥作用已经很简单了。


一切都通过内核。 eBPF 提供了一种高性能且安全的方式来观察内核中的所有内容。


让我们更深入地研究可观察性,看看这项技术的含义。

eBPF 到底是如何影响可观察性的?

为了探索这一点,让我们走出 eBPF 领域,进入可观察性领域,看看是什么构成了我们的标准可观察性解决方案。


任何可观察性解决方案都有 4 个主要组成部分 -


  1. 数据收集——从应用程序和基础设施获取遥测数据

  2. 数据处理——对收集到的数据进行过滤、索引和计算

  3. 数据存储- 数据的短期和长期存储

  4. 用户体验层——决定用户如何使用数据


其中,eBPF 的影响(截至目前)实际上只是数据收集层——使用 eBPF 直接从内核轻松收集遥测数据。


eBPF 对可观察性的影响


因此,当我们今天说“eBPF 可观察性”时,我们的意思是使用 eBPF 作为检测机制来收集遥测数据,而不是使用其他检测方法。可观察性解决方案的其他组件不受影响。


eBPF 可观察性如何工作

要完全理解 eBPF 可观察性背后的底层机制,我们需要理解钩子的概念。


正如我们之前看到的,eBPF 程序主要是事件驱动的——即,它们会在特定事件发生时被触发。例如,每次进行函数调用时,都可以调用 eBPF 程序来捕获一些数据以用于可观察性目的。


首先,这些钩子可以在内核空间或用户空间。因此 eBPF 可用于监视用户空间应用程序和内核级事件。


其次,这些挂钩可以是预先确定的/静态的,也可以动态插入到正在运行的系统中(无需重新启动!)


四种不同的 eBPF 机制允许其中的每一种(见下图)



预定/手动

动态的

核心

内核跟踪点

k探针

用户空间

泰达币

探针


静态和动态 eBPF 挂钩到用户空间和内核空间


  1. 内核跟踪点- 用于挂钩内核开发人员预定义的事件(使用 TRACE_EVENT 宏)

  2. USDT - 用于挂钩开发人员在应用程序代码中设置的预定义跟踪点

  3. Kprobes (Kernel Probes) - 用于在运行时动态挂钩到内核代码的任何部分

  4. Uprobes (User Probes) - 用于在运行时动态连接到用户空间应用程序的任何部分


内核空间中有几个预定义的挂钩,可以轻松地将 eBPF 程序附加到这些挂钩(例如,系统调用、函数入口/出口、网络事件、内核跟踪点)。同样在用户空间中,许多语言运行时、数据库系统和软件堆栈都公开了 Linux BCC 工具的预定义挂钩,eBPF 程序可以挂接到这些挂钩中。


不过比较有意思的是kprobes和uprobes。如果生产中出现问题并且我没有足够的信息并且我想在运行时动态添加检测怎么办?这就是 kprobes 和 uprobes 允许强大的可观察性的地方。


eBPF kprobes 和 uprobes 如何工作


例如,使用 uprobe,可以在运行时挂钩到应用程序中的特定函数,而无需修改应用程序的代码。每当执行该函数时,都会触发一个 eBPF 程序来捕获所需的数据。这允许令人兴奋的可能性,如实时调试。


现在我们知道了 eBPF 的可观察性是如何工作的,让我们看看用例。

eBPF 可观察性用例

eBPF 可用于几乎所有常见的现有可观察性用例,此外还开辟了新的可能性。


  1. 系统和基础设施监控: eBPF 允许深入监控系统级事件,例如 CPU 使用率、内存分配、磁盘 I/O 和网络流量。例如, LinkedIn 使用 eBPF 进行所有的基础设施监控


  2. 容器和 Kubernetes 监控:查看特定于 Kubernetes 的指标、资源使用情况以及单个容器和 pod 的运行状况。


  3. 应用程序性能监控 (APM):对用户空间应用程序的细粒度可观察性以及对应用程序吞吐量、错误率、延迟和跟踪的可见性。


  4. 自定义可观察性:对特定于应用程序或基础设施的自定义指标的可见性,如果不编写自定义代码则可能不容易获得这些指标。


  5. 高级可观察性: eBPF 可用于高级可观察性用例,例如实时调试低开销应用程序分析系统调用跟踪


每天都有 eBPF 在可观察性方面的新应用出现。


这对今天如何进行可观察性意味着什么? eBPF 是否有可能取代现有形式的仪器?让我们与现有选项进行比较。

eBPF 与现有的检测方法

今天,除了 eBPF 之外,还有两种主要的方法来检测应用程序和基础设施的可观察性。


  1. 基于代理的检测:集成到应用程序代码或基础设施节点中以收集遥测数据的独立软件 SDK/库。


  1. 基于 Sidecar 代理的检测:Sidecar 是与应用程序或服务一起运行的轻量级独立进程。它们在微服务和基于容器的架构(如 Kubernetes)中很受欢迎。


有关基于 eBPF 的检测与代理和边车的详细比较,请参见此处。以下是摘要视图 -



eBPF

代理商

边车

1.数据可见性/粒度

(但有些差距)

高的

低的

2.侵入性

(带外)

(内联)

(内联)

3.性能开销

低的

中等的

高的

4. 安全保障

高的

中等的

中等的

5.易于实施

高的

低的

中等的

6. 易于维护和更新

高的

低的

中等的

7.可扩展性

高的

中等的

低的



正如我们所见,eBPF 在几乎所有参数上都优于现有的检测方法。有几个好处 -


  1. 可以一次性涵盖所有内容(基础设施、应用程序)

  2. 更少侵入性——eBPF 不是内联运行的工作负载,例如每次工作负载运行时都会运行的代码代理。数据收集是带外和沙盒的,因此对正在运行的系统没有影响。

  3. 低性能开销——eBPF 作为本地机器代码运行,没有上下文切换。

  4. 更安全- 由于采用了验证等内置安全措施。

  5. 易于安装- 无需任何代码更改或重新启动即可投入使用。

  6. 易于维护和更新- 同样无需更改代码和重新启动。

  7. 更具可扩展性- 由易于实施和维护以及低性能开销驱动


就缺点而言,当今 eBPF 可观察性的主要差距在于分布式跟踪(可行,但用例仍处于早期阶段)。


总而言之,鉴于 eBPF 相对于现有仪器方法的显着优势,我们可以合理地预期 eBPF 将成为默认的下一代仪器平台。

对可观察性的影响

这对可观察性行业意味着什么?有什么变化?

想象一个可观察性解决方案:


  • 你可以在 5 分钟内进入内核

  • 没有代码更改或重新启动

  • 一次涵盖所有内容 - 基础架构、应用程序、所有内容

  • 开销几乎为零

  • 非常安全


这就是 eBPF 使之成为可能的原因。这就是为什么人们对这项技术如此兴奋的原因。


我们可以期待下一代可观察性解决方案都使用 eBPF 而不是代码代理进行检测。


Datadog 和 NewRelic 等传统参与者已经在投资构建基于 eBPF 的工具,以扩充其基于代码的代理产品组合。同时,有几家基于 eBPF 构建的下一代供应商,解决了利基用例复杂的可观察性问题


虽然传统参与者必须在几年内逐个语言地为每个基础设施组件构建单独的代码代理,但新参与者可以在几个月内使用 eBPF 获得相同程度的覆盖。这使他们还可以专注于创新价值链的更高层次,例如数据处理、用户体验,甚至人工智能。此外,他们的数据处理和用户体验层也是全新构建的,以支持新的用例、数量和频率。


所有这些都应该推动这一领域的大量创新,并在未来几年使可观察性更加无缝、安全和易于实施。

谁应该使用 eBPF 可观察性?

首先,如果您处于现代云原生环境(Kubernetes、微服务)中,那么基于 eBPF 和基于代理的方法之间的差异最为明显(性能开销、安全性、易于安装等)。


其次,如果你在大规模运营,那么基于 eBPF 的轻量级代理将推动对现状的显着改进。这可能是 eBPF 在 LinkedIn、Netflix 和 Meta 等拥有大量足迹的科技公司中采用率最高的原因之一。


第三,如果你缺乏技术。容量并正在寻找几乎不需要安装和维护的可观察性解决方案,然后直接寻求基于 eBPF 的解决方案。

概括

总之,通过提供明显更好的检测机制,eBPF 有可能在未来几年从根本上重塑我们的可观察性方法。


虽然在本文中我们主要探讨了 eBPF 在数据收集/检测中的应用,但未来的应用可能会看到 eBPF 用于数据处理甚至数据存储层。可能性是广泛的,但尚未探索。

参考

  1. https://www.oreilly.com/library/view/learning-ebpf/9781098135119/ch01.html
  2. https://ebpf.io/
  3. https://ebpf.io/summit-2022.html
  4. https://github.com/microsoft/ebpf-for-windows
  5. https://events.linuxfoundation.org/wp-content/uploads/2022/10/elena-zannoni-tracing-tutorial-LF-2021.pdf


也发布在这里。