为什么说eBPF对可观测性很重要?

eBPF的由来

当我们想要实现安全、网络和可观测性功能时,我们往往会选择基于Linux内核来实现,因为这种方式可以具备性能好、灵活性高等优点。然而,基于内核实现通常是比较困难和繁琐的。在传统基于内核实现的方式中,开发人员可能需要去修改内核源代码再重新编译或者是通过加载内核模块的方式来实现,这时开发人员会发现自己要应对复杂的基础设施和难以调试的抽象层,非常棘手。而如果我们采用eBPF技术,则既不需要修改内核,也不需要添加其他模块,可以很好地解决上述问题。 

                          为什么说eBPF对可观测性很重要?_第1张图片 

图1 eBPF技术与传统方式比较图

扩展伯克利数据包过滤器 (eBPF) 是一种内核技术(从 Linux 4.x 开始),它无需更改内核源代码或添加其他模块便可以运行用户植入内核中的程序。我们可以将它看作是 Linux 内核中的轻量级虚拟机 (VM),程序员可以在其中运行自己想要内核去做的一些程序。

                 为什么说eBPF对可观测性很重要?_第2张图片

图2 BPF架构原理图

使用 eBPF 技术无需更改内核源代码,开发人员只需要将自己写好的程序注入到内核中去解释执行即可,十分便捷。因此,它是一项强大的技术,有可能从根本上改变网络、可观测性和安全等服务的交付方式。

下文将详细介绍它是什么、它是如何工作的以及我们应该在什么时候使用它。

eBPF的工作原理

用户编写的eBPF程序代码将被编译为 BPF 字节码,而字节码在运行之前会经过验证,以确保它不会带有循环(此前出于安全性考虑,eBPF不支持带有循环的附加程序代码,在Linux 5.3之后开始支持有限循环代码),此步骤可防止程序有意或无意地损害Linux 内核。

通过验证后的eBPF 程序被关联在一个被称为“hook(钩子) “的触发器上,这些hook在被访问到时将执行该eBPF 程序(由一些特定事件来触发hook)。举例来说,假设现在有某kprobes类型的hook关联了一段eBPF程序,当执行到该kprobes的地址时将会唤醒kprobes的回调函数,同时触发eBPF程序的执行(有关hook的具体实例有network events(网络事件)、system calls(系统调用)、functions entries(函数入口)和kernel tracepoints(内核跟踪点)等)。

在hook处触发程序后,它会进行Helper调用。这些Helper调用为 eBPF 配备了许多访问内核功能的函数,Helper 调用需要由内核预先定义。 

eBPF 最初是用作过滤网络数据包时提高可观测性和安全性的一种方式。然而,随着时间的推移,它成为一种使用户代码的实现更安全、更方便、性能更好的方式。

           为什么说eBPF对可观测性很重要?_第3张图片 

图3 BPF执行原理图

eBPF的优势

eBPF 技术通常被用于跟踪用户进程,它的优势在这里大放异彩。这是一种安全且有用的方法,具体有以下几个优势:

1. 速度和性能。 eBPF 可以将数据包处理这项工作从内核空间转移到用户空间。同时,eBPF 还支持即时 (JIT) 编译器。在字节码被(JIT)编译完成后,会直接调用 eBPF,而不是对每个方法的字节码进行新的解释。

为什么说eBPF对可观测性很重要?_第4张图片

图4 BPF编译执行原理图

2. 低侵入性。 当作为调试器时,eBPF 不需要停止程序来观察其状态。

3. 安全。 程序被有效地沙箱化了,这意味着内核源代码仍然受到保护并保持不变。eBPF程序的验证步骤确保资源不会被运行无限循环的程序阻塞。

4. 方便。 创建hook内核函数的代码比构建和维护内核模块的工作要少。

5. 统一追踪。 eBPF 为我们提供了一个单一、强大且易于访问的流程跟踪框架,这增加了可见性和安全性。

6. 可编程性。 使用 eBPF 有助于在不添加额外层的情况下增加环境的功能丰富性。由于代码直接在内核中运行,因此可以在 eBPF 事件之间存储数据,而不是像其他跟踪器那样转储数据。

7. 表现力。 eBPF 具有丰富的表现力,能够执行通常只能在高级语言中才能找到的功能。

eBPF 最佳实践

由于 eBPF 是一项新技术,因此还有许多事情尚未探索。随着 eBPF 技术的日益突出,围绕 eBPF 的最佳实践仍在不断发展。虽然不存在定义好的一组最佳实践,但我们可以采取一些措施来确保程序变得有效且高效。

如果你想要在生态系统中使用 eBPF,有以下建议:

1. 使用 LLVM Clang 将 C 编译成字节码。 当 eBPF 首次出现时,需要手动编码和组装程序。然后,开发人员使用内核的汇编程序生成字节码。幸运的是,现在不再需要这样做了。Clang 为 C 语言的前端和工具提供了基础设施。 

2. 编写 BPF 程序时使用 BCC 工具包。 该 BPF编译器集合 (BCC)是一个工具包,可以帮助我们创建高效的内核跟踪和操作程序。它特别适用于与性能分析和控制网络流量相关的任务。

eBPF 的陷阱

虽然eBPF很强大,但 eBPF 并不是适合每个项目或生态系统的灵丹妙药。事实上,eBPF 有一些显著的缺点,这可能会使它在某些情况下的表现不尽如人意。一些开发人员可能会发现 eBPF 不适合使用,因为:

1. 它仅限于 Linux 和最新的内核。 eBPF 是在 Linux 内核中开发的,这使得它不如其他tracers便携。此外,开发人员需要一个相当新的内核。如果运行的版本早于 v 4.13,则将无法使用它。

2. 沙盒程序是有限的。 eBPF 通过限制程序可以访问的资源来提高安全性。但是,通过限制程序可以访问的操作系统部分,其功能也可能受到限制。

eBPF 通常情况下表现不错

eBPF 在云原生应用中迅速获得关注 。因此,eBPF 最常用于两种情况:

1. 需要使用内核跟踪来实现可观性。 在这种情况下,eBPF 会更快更准确,不涉及上下文切换,而且 eBPF 程序是基于事件的,因此没有特定触发器就不会运行任何东西。 

2. 传统的安全监控不起作用。 eBPF 在分布式和基于容器的环境中有很多用途,包括 Kubernetes。在这些环境中,eBPF 可以缩小可见性差距,因为它可以提供对HTTP 流量的可见性 。

除此以外,有关eBPF还有其他的一些例子,比如防火墙、设备驱动程序和网络性能监控等。

eBPF 使可观测性变得高效

eBPF 是一项提高 Linux 内核中的可观测性、网络和安全性的新技术。它消除了更改内核源代码或添加模块的需要,我们可以更加简单且灵活地创建更丰富的基础架构来支持你的系统。 

本文改编自CNCF:

What is eBPF and why does it matter for observability? | Cloud Native Computing Foundation

参考资料:

[1] https://www.cncf.io/

[2] https://github.com/DavadDi/bpf_study

[3] eBPF - Introduction, Tutorials & Community Resources

[4] A thorough introduction to eBPF [LWN.net]

在云可观测性方面有任何疑问欢迎与我们联系: Kindling官网

你可能感兴趣的:(linux,运维,服务器,云原生)