让我们来看看eBPF——这项技术到底是什么,它如何影响观测性,它与现有的观测性实践有什么区别,未来可能会发生什么变化?
在过去的两年里,云原生社区一直在热烈讨论eBPF。eBPF曾是KubeCon、eBPF Days和eBPF Summit的主题,并且越来越受欢迎。像Google和Netflix这样的公司多年来一直在使用eBPF,新的用例也不断涌现。特别是在观测性方面,eBPF被认为将是一个重大改变。
所以让我们来看看eBPF——这项技术到底是什么,它如何影响观测性,它与现有的观测性实践有什么区别,未来可能会发生什么变化?

eBPF是一种编程框架,允许我们在Linux内核中安全地运行沙盒化的程序,而无需更改内核代码。
它最初是为Linux开发的(而且直到今天,这项技术在Linux上最成熟),但微软正在迅速发展eBPF在Windows上的实现[1]。
eBPF程序从设计上来说非常高效和安全——内核会对其进行验证,以确保它们不会危及操作系统的稳定性或安全性。
要理解这一点,我们需要了解用户空间和内核空间。
用户空间是所有应用程序运行的地方。内核空间位于用户空间和物理硬件之间。用户空间中的应用程序无法直接访问硬件。相反,它们通过系统调用与内核通信,然后内核再访问硬件。
所有内存访问、文件读写和网络流量都经过内核。内核还管理并发进程。
基本上,所有操作都通过内核进行(见下图)。
而eBPF提供了一种安全的、高效的扩展内核功能的方式。

用户空间和内核空间
从历史上看,出于显而易见的原因,更改内核源代码或操作系统层的任何内容一直都非常困难。
Linux内核有3000万行代码[2],任何更改要从一个想法变成广泛可用的东西需要数年时间。首先,Linux社区必须同意它。然后,它必须成为官方Linux发布的一部分。然后,在几个月后,它会被Red Hat和Ubuntu等发行版采用,然后传播到更广泛的用户。
从技术上讲,一个人可以将内核模块加载到内核中,直接进行更改,但这是非常高风险的,涉及复杂的内核级编程,因此几乎普遍不建议这样做。
eBPF出现并解决了这个问题,提供了一种在内核中附加和运行程序的安全和高效机制。
让我们看看eBPF如何确保安全性和性能。
因此,eBPF为内核编程提供了一种安全且高效的钩子。考虑到一切都通过内核,这为我们带来了以前无法实现的新可能性。
eBPF周围的技术在很长一段时间内得以发展,已经有大约30年了。
在过去的7-8年中,eBPF已被一些大型公司大规模使用,现在我们正在进入一个使用eBPF变得更加主
流的时代。请参阅eBPF的共同创作者之一、Linux的共同维护者Alexei Starovoitov的这个视频[3],了解eBPF的发展历程。
之所以说这个发布很重要,是因为它使得扩展内核功能变得容易。
程序员可以更多或更少地像编写常规应用程序一样编写代码,而周围的eBPF基础设施会处理低级验证、安全性和效率问题。
eBPF的周围支持生态系统和脚手架使这成为可能(见下图)。

来源:https://ebpf.io/what-is-ebpf/
更好的是,eBPF程序可以在不重新启动的情况下加载到内核中,并且可以随时卸载。
所有这些突然使得广泛采用和应用成为可能。
eBPF的受欢迎程度在过去的7-8年中迅速增长,许多大型公司在规模生产系统中使用它。
现在有成千上万家公司使用eBPF,并且每年涌现出数百个eBPF项目,探索不同的用例。
eBPF现在是Linux内核中的一个独立子系统,并拥有广泛的社区支持。这项技术本身也在不断扩展,有了几个新的添加。
eBPF的最常见用途可以分为三个领域:
安全和网络已经看到了更广泛的采用和应用,其中包括像Cilum[12]这样的项目。相比之下,基于eBPF的可观测性方案在其演进过程中还处于早期阶段。
让我们首先看看安全和网络的用例。
(1) 安全
安全是eBPF的一个非常流行的用例。使用eBPF,程序可以观察内核级别的一切情况,以高速处理事件以检查意外行为,并比以前更快地发出警报。
例如 -
一些第三方安全产品[15]现在使用eBPF进行数据收集和监视。
(2) 网络
网络是另一个广泛应用的用例。位于eBPF层的位置允许全面监测网络可观测性,例如完整网络路径的可见性,包括所有跳数,以及源IP和目标IP。使用eBPF程序,可以处理高速网络事件并在内核内直接操作网络数据包,而开销非常低。
这允许各种网络用例,如负载平衡、DDoS防护、流量整形和服务质量(QoS)。
(3) 可观测性
到目前为止,通过内核观察一切并且eBPF提供了一种高性能和安全的方式来观察一切,这使得eBPF在可观察性方面非常有用。
让我们更深入地探讨可观测性,看看这项技术的影响。
为了探讨这一点,让我们离开eBPF的世界,进入可观测性的世界,看看构成我们标准可观测性解决方案的内容。
任何可观测性解决方案都有四个主要组件:
1.数据收集 — 从应用程序和基础设施获取遥测数据2.数据处理 — 对收集的数据进行过滤、索引和计算3.数据存储 — 数据的短期和长期存储4.用户体验层 — 确定用户如何使用数据
在这些组件中,eBPF影响的是(截至今天)仅仅是数据收集层 — 使用eBPF直接从内核收集遥测数据的简便机制。

0*8zMD7h66uFLgBIJH.png
eBPF — 对可观测性的影响
所以当我们说“eBPF可观测性”时,我们实际上是指使用eBPF作为收集遥测数据的工具,而不是使用其他方法来进行仪器化。可观测性解决方案的其他组件保持不变。
为了充分理解eBPF可观测性背后的机制,我们需要了解挂钩(hooks)的概念。
正如我们前面所看到的,eBPF程序主要是事件驱动的,即每次发生特定事件时都会触发它们。例如,每次进行函数调用时,都可以调用一个eBPF程序来捕获一些用于可观测性目的的数据。
这四种不同的eBPF机制允许每一种(见下图)

1*_e2Q4FEhTJhkK2nVYkiICw.png
用户空间和内核空间的静态和动态eBPF挂钩:
在内核空间中有许多预定义的挂钩,可以轻松将eBPF程序附加到其中(例如,系统调用、函数入口/出口、网络事件、内核跟踪点)。类似地,在用户空间中,许多语言运行时、数据库系统和软件堆栈会暴露出Linux BCC工具的预定义挂钩,eBPF程序可以连接到这些挂钩。
但更有趣的是kprobes和uprobes。如果生产中出现问题,我没有足够的信息,并且我希望在运行时动态添加仪表化,该怎么办?这就是kprobes和uprobes允许强大的可观测性的地方。

0*4BZtZLhHeUsGWSc1.png
eBPF kprobes 和 uprobes:
例如,使用uprobes,可以在不修改应用程序代码的情况下在运行时挂接到应用程序内的特定函数。每当执行该函数时,都会触发一个eBPF程序以捕获所需的数据。这允许像实时[19]调试这样的令人兴奋的可能性。
现在我们知道了eBPF可观测性是如何工作的,让我们来看看用例。
eBPF可用于几乎所有常见的现有可观测性用例,并且还提供了新的可能性。
(1) 系统和基础设施监控
在这个领域,eBPF最常用于监控Linux主机的性能和资源使用情况。
eBPF程序可以轻松地在这些事件的发生时捕获数据,并将其发送到存储后端,以便稍后分析。
(2) 应用程序性能监控(APM)
eBPF也用于应用程序内部的性能监控。例如,在Go应用程序中,可以使用uprobes挂接到某个特定函数,以捕获函数参数、返回值和执行时间。这对于详细分析应用程序性能问题非常有用。
(3) 安全监控
eBPF在安全监控方面也非常有用。它可以用于检测恶意行为、网络攻击和异常事件。eBPF程序可以在内核和应用程序级别捕获事件,并将其传递给安全信息和事件管理系统,以进行进一步的分析和响应。
(4) 故障排除
eBPF还可以用于故障排除。它可以用于跟踪应用程序崩溃、性能下降或其他问题的根本原因。eBPF程序可以捕获关键性能指标、事件和上下文信息,以帮助诊断问题并进行修复。
以下是一些eBPF可观测性用例的实际示例:
现在让我们来比较eBPF可观测性和传统观测性方法。
(1) 传统观测性
传统的可观测性方法通常基于以下原则:
(2) eBPF可观测性
与传统观测性方法相比,eBPF可观测性具有以下优势:
尽管eBPF可观测性具有许多优势,但它也具有一些挑战和限制。首先,eBPF编程需要一定的学习曲线,因为它涉及到特定的编程模型和语言。此外,某些高级用例可能需要更复杂的eBPF程序。
eBPF可观测性已经取得了巨大的进展,但仍有很多潜在的未来发展方向。
总之,eBPF可观测性是一个充满潜力的领域,已经取得了令人印象深刻的进展。它提供了一种强大而灵活的方式来观察和监视应用程序和基础设施的行为,有望在未来继续发展和成熟。对于那些希望更好地了解和控制其系统的用户来说,eBPF可观测性是一个令人兴奋的选择。