6

解码eBPF可观测性:eBPF如何改变我们所知的观测性

 7 months ago
source link: https://www.51cto.com/article/769769.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

解码eBPF可观测性:eBPF如何改变我们所知的观测性

作者:小技术君 2023-10-13 13:40:29
让我们来看看eBPF——这项技术到底是什么,它如何影响观测性,它与现有的观测性实践有什么区别,未来可能会发生什么变化?

在过去的两年里,云原生社区一直在热烈讨论eBPF。eBPF曾是KubeCon、eBPF Days和eBPF Summit的主题,并且越来越受欢迎。像Google和Netflix这样的公司多年来一直在使用eBPF,新的用例也不断涌现。特别是在观测性方面,eBPF被认为将是一个重大改变。

所以让我们来看看eBPF——这项技术到底是什么,它如何影响观测性,它与现有的观测性实践有什么区别,未来可能会发生什么变化?

c5de3b638663f1e02225899881557d8bf46d3d.png

什么是eBPF?

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

它最初是为Linux开发的(而且直到今天,这项技术在Linux上最成熟),但微软正在迅速发展eBPF在Windows上的实现[1]。

eBPF程序从设计上来说非常高效和安全——内核会对其进行验证,以确保它们不会危及操作系统的稳定性或安全性。

为什么eBPF如此重要?

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

用户空间是所有应用程序运行的地方。内核空间位于用户空间和物理硬件之间。用户空间中的应用程序无法直接访问硬件。相反,它们通过系统调用与内核通信,然后内核再访问硬件。

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

基本上,所有操作都通过内核进行(见下图)。

而eBPF提供了一种安全的、高效的扩展内核功能的方式。

e1d759c0881e88eb0f8499b12a1fd5384be3fa.png

用户空间和内核空间

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

Linux内核有3000万行代码[2],任何更改要从一个想法变成广泛可用的东西需要数年时间。首先,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变得更加主

流的时代。请参阅eBPF的共同创作者之一、Linux的共同维护者Alexei Starovoitov的这个视频[3],了解eBPF的发展历程。

eBPF — 简要历史

  • 1993年-来自劳伦斯伯克利国家实验室的一篇论文[4]探讨了使用内核代理进行数据包过滤。这就是BPF(“伯克利数据包过滤器”)这个名字的由来。
  • 1997年 — BPF正式作为Linux内核的一部分引入(版本2.1.75)。
  • 1997–2014年 — 添加了一些功能,以改进、稳定和扩展BPF的功能。
  • 2014年 — 引入了重要的更新,称为“扩展伯克利数据包过滤器”(eBPF)。这个版本对BPF技术进行了重大改进,使其更广泛可用,因此称之为“扩展”。

之所以说这个发布很重要,是因为它使得扩展内核功能变得容易。

程序员可以更多或更少地像编写常规应用程序一样编写代码,而周围的eBPF基础设施会处理低级验证、安全性和效率问题。

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

17b305230ee42c29297259a18ad7518db1a30d.png

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

更好的是,eBPF程序可以在不重新启动的情况下加载到内核中,并且可以随时卸载。

所有这些突然使得广泛采用和应用成为可能。

在生产系统中的广泛应用

eBPF的受欢迎程度在过去的7-8年中迅速增长,许多大型公司在规模生产系统中使用它。

  • 到2016年,Netflix广泛使用eBPF进行跟踪。Brendan Gregg[5]实现了它,他在基础设施和运维领域被广泛认为是eBPF的权威人士。
  • 2017年 — Facebook开源了他们基于eBPF的负载均衡器Katran[6]。自2017年以来,每个访问Facebook.com[7]的数据包都经过了eBPF。
  • 2020年- Google将eBPF纳入其Kubernetes提供的一部分。eBPF现在驱动着GKE的网络、安全和可观测性层[8]。到目前为止,企业中也有广泛的采用,如Capital One[9]和Adobe[10]。
  • 2021年 — Facebook、Google、Netflix、Microsoft和Isovalent联合宣布创建eBPF基金会[11]来管理eBPF技术的增长。

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

eBPF现在是Linux内核中的一个独立子系统,并拥有广泛的社区支持。这项技术本身也在不断扩展,有了几个新的添加。

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

eBPF的最常见用途可以分为三个领域:

安全和网络已经看到了更广泛的采用和应用,其中包括像Cilum[12]这样的项目。相比之下,基于eBPF的可观测性方案在其演进过程中还处于早期阶段。

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

(1) 安全

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

  • Google[13]使用eBPF进行大规模入侵检测
  • Shopify[14]使用eBPF来实现容器安全

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

(2) 网络

网络是另一个广泛应用的用例。位于eBPF层的位置允许全面监测网络可观测性,例如完整网络路径的可见性,包括所有跳数,以及源IP和目标IP。使用eBPF程序,可以处理高速网络事件并在内核内直接操作网络数据包,而开销非常低。

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

  • Cloudflare[16]使用eBPF检测并防止DDoS攻击,每秒处理1000万个数据包[17]而不影响网络性能。
  • Meta的基于eBPF的Katran[18]为Facebook的所有负载均衡进行处理

(3) 可观测性

到目前为止,通过内核观察一切并且eBPF提供了一种高性能和安全的方式来观察一切,这使得eBPF在可观察性方面非常有用。

让我们更深入地探讨可观测性,看看这项技术的影响。

eBPF如何确切影响可观测性?

为了探讨这一点,让我们离开eBPF的世界,进入可观测性的世界,看看构成我们标准可观测性解决方案的内容。

任何可观测性解决方案都有四个主要组件:

1.数据收集 — 从应用程序和基础设施获取遥测数据2.数据处理 — 对收集的数据进行过滤、索引和计算3.数据存储 — 数据的短期和长期存储4.用户体验层 — 确定用户如何使用数据

在这些组件中,eBPF影响的是(截至今天)仅仅是数据收集层 — 使用eBPF直接从内核收集遥测数据的简便机制。

145d50f30e8d9dc4e134405ba4a820795b9e1b.png

0*8zMD7h66uFLgBIJH.png

eBPF — 对可观测性的影响

所以当我们说“eBPF可观测性”时,我们实际上是指使用eBPF作为收集遥测数据的工具,而不是使用其他方法来进行仪器化。可观测性解决方案的其他组件保持不变。

eBPF可观测性的工作原理

为了充分理解eBPF可观测性背后的机制,我们需要了解挂钩(hooks)的概念。

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

  • 首先,这些挂钩可以在内核空间或用户空间。因此,eBPF可以用于监视用户空间应用程序以及内核级事件。
  • 其次,这些挂钩可以是预定义的/静态的,也可以在运行中动态插入到系统中(无需重新启动!)

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

f846a69650464a05e470318dff008d05e23a81.png

1*_e2Q4FEhTJhkK2nVYkiICw.png

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

  • 内核跟踪点 — 用于挂接到由内核开发人员预定义的事件(使用TRACE_EVENT宏)
  • USDT — 用于挂接到应用程序代码中由开发人员预定义的跟踪点
  • Kprobes(内核探针) — 用于在运行时动态挂接到内核代码的任何部分
  • Uprobes(用户探针) — 用于在运行时动态挂接到用户空间应用程序的任何部分

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

但更有趣的是kprobes和uprobes。如果生产中出现问题,我没有足够的信息,并且我希望在运行时动态添加仪表化,该怎么办?这就是kprobes和uprobes允许强大的可观测性的地方。

7676fa914891980093a431c2094158d005980e.png

0*4BZtZLhHeUsGWSc1.png

eBPF kprobes 和 uprobes:

例如,使用uprobes,可以在不修改应用程序代码的情况下在运行时挂接到应用程序内的特定函数。每当执行该函数时,都会触发一个eBPF程序以捕获所需的数据。这允许像实时[19]调试这样的令人兴奋的可能性。

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

eBPF可观测性用例

eBPF可用于几乎所有常见的现有可观测性用例,并且还提供了新的可能性。

  • 系统和基础设施监控
  • 应用程序性能监控(APM)

(1) 系统和基础设施监控

在这个领域,eBPF最常用于监控Linux主机的性能和资源使用情况。

  • CPU和内存使用率
  • 硬盘和网络性能
  • 进程活动和调度
  • 文件系统活动

eBPF程序可以轻松地在这些事件的发生时捕获数据,并将其发送到存储后端,以便稍后分析。

(2) 应用程序性能监控(APM)

eBPF也用于应用程序内部的性能监控。例如,在Go应用程序中,可以使用uprobes挂接到某个特定函数,以捕获函数参数、返回值和执行时间。这对于详细分析应用程序性能问题非常有用。

(3) 安全监控

eBPF在安全监控方面也非常有用。它可以用于检测恶意行为、网络攻击和异常事件。eBPF程序可以在内核和应用程序级别捕获事件,并将其传递给安全信息和事件管理系统,以进行进一步的分析和响应。

(4) 故障排除

eBPF还可以用于故障排除。它可以用于跟踪应用程序崩溃、性能下降或其他问题的根本原因。eBPF程序可以捕获关键性能指标、事件和上下文信息,以帮助诊断问题并进行修复。

以下是一些eBPF可观测性用例的实际示例:

  • Tracing和Profiling — 使用eBPF捕获应用程序的性能数据,例如函数调用、系统调用和内存分配,以识别瓶颈和优化性能。
  • 网络可观测性 — 使用eBPF来监视网络流量、分析网络包,并实施防火墙策略和负载平衡。
  • 容器监控 — 在Kubernetes集群中,使用eBPF来监控容器内部的资源使用情况、性能和问题。
  • 安全监控 — 使用eBPF来检测潜在的安全威胁,例如异常网络活动、不寻常的系统调用和入侵尝试。
  • 分布式跟踪 — 使用eBPF捕获应用程序的分布式跟踪数据,以分析请求的流经整个系统的路径,帮助诊断和优化性能问题。

eBPF和传统观测性的比较

现在让我们来比较eBPF可观测性和传统观测性方法。

(1) 传统观测性

传统的可观测性方法通常基于以下原则:

  • 代理和代理集成 — 在目标系统中安装代理,代理负责收集和传输遥测数据。这通常需要在每个目标系统上部署代理,而且代理也需要进行版本控制和维护。
  • 度量指标集成 — 需要配置和管理度量和日志指标的集成。这通常涉及到手动配置和更新,以确保适当的指标和日志数据被采集。
  • 额外的开销 — 代理需要在目标系统上运行,这可能会引入额外的开销,例如CPU和内存消耗。
  • 局限性 — 传统的可观测性方法可能会受到系统复杂性和性能问题的限制,因为它们可能无法实时捕获足够的数据。
  • 安全性 — 代理可能会引入潜在的安全风险,因为它们在目标系统上运行并访问敏感数据。

(2) eBPF可观测性

与传统观测性方法相比,eBPF可观测性具有以下优势:

  • 内核级别的可观测性 — eBPF程序在内核级别运行,可以观察系统的内部状态和事件,无需在目标系统上运行代理。
  • 轻量级 — eBPF程序通常对系统资源的开销很小,因为它们在内核级别运行,无需独立的代理。
  • 安全性 — eBPF程序受到内核验证器的强制约束,以确保它们不会引入安全风险。
  • 灵活性 — eBPF程序可以在运行时动态附加到系统中,无需重新启动目标系统,从而提供了更大的灵活性和可伸缩性。
  • 性能 — eBPF程序通常以本机机器指令运行,因此性能很高,可以实时捕获大量数据。

尽管eBPF可观测性具有许多优势,但它也具有一些挑战和限制。首先,eBPF编程需要一定的学习曲线,因为它涉及到特定的编程模型和语言。此外,某些高级用例可能需要更复杂的eBPF程序。

eBPF可观测性已经取得了巨大的进展,但仍有很多潜在的未来发展方向。

  • 更多的工具和库 — 随着eBPF的流行,可以预期会有更多的工具和库出现,用于简化eBPF程序的开发、调试和部署。
  • 标准化 — 随着eBPF的广泛应用,可以期待出现更多的标准和最佳实践,以帮助开发人员更轻松地使用eBPF进行可观测性。
  • 更广泛的集成 — eBPF将继续集成到各种云计算和容器平台中,以帮助用户监控和调试分布式应用程序。
  • 更多的可观测性用例 — 随着eBPF技术的不断发展,可以预期将出现更多的创新可观测性用例,帮助用户更好地了解和优化其应用程序和基础设施的性能。

总之,eBPF可观测性是一个充满潜力的领域,已经取得了令人印象深刻的进展。它提供了一种强大而灵活的方式来观察和监视应用程序和基础设施的行为,有望在未来继续发展和成熟。对于那些希望更好地了解和控制其系统的用户来说,eBPF可观测性是一个令人兴奋的选择。

  • [1] eBPF在Windows上的实现: https://github.com/microsoft/ebpf-for-windows
  • [2] 3000万行代码: https://www.phoronix.com/news/Linux-5.12-rc1-Code-Size
  • [3] 这个视频: https://www.youtube.com/watch?v=DAvZH13725I
  • [4] 论文: https://www.tcpdump.org/papers/bpf-usenix93.pdf
  • [5] Brendan Gregg: https://www.brendangregg.com/
  • [6] Katran: https://engineering.fb.com/2018/05/22/open-source/open-sourcing-katran-a-scalable-network-load-balancer/
  • [7] Facebook.com: http://facebook.com/
  • [8] 网络、安全和可观测性层: https://cloud.google.com/blog/products/containers-kubernetes/bringing-ebpf-and-cilium-to-google-kubernetes-engine
  • [9] Capital One: https://www.youtube.com/watch?v=hwOpCKBaJ-w
  • [10] Adobe: https://www.youtube.com/watch?v=7UQ2CU6UEGY
  • [11] 创建eBPF基金会: https://isovalent.com/blog/post/2021-08-ebpf-foundation-announcement/
  • [12] Cilum: https://github.com/cilium/cilium
  • [13] Google: https://www.youtube.com/watch?v=l8jZ-8uLdVU
  • [14] Shopify: https://www.youtube.com/watch?v=6pVci31Mb6Q
  • [15] 第三方安全产品: https://www.traceable.ai/blog-post/ebpf-and-api-security-with-traceable
  • [16] Cloudflare: https://legacy.netdevconf.info/2.1/session.html?bertin=
  • [17] 1000万个数据包: https://blog.cloudflare.com/how-to-drop-10-million-packets/
  • [18] Katran: https://engineering.fb.com/2018/05/22/open-source/open-sourcing-katran-a-scalable-network-load-balancer/
  • [19] 实时: https://www.cncf.io/blog/2021/11/17/debugging-with-ebpf-part-1-tracing-go-function-arguments-in-prod/

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK