博客 | 首席技术官办公室

eBPF: 一切都关乎可观察性

James Hendergart 缩略图
詹姆斯·亨德加特
2022 年 6 月 14 日发布


有时,一项很酷的技术会达到一个转折点,真正的商业需求与该技术的优势相交叉。 这使得该技术不仅可行而且实用。 伯克利数据包过滤器(BPF) 最近在 Linux 开发人员中达到了这一点。 BPF 是 Linux 主机上一个非常高效的拦截和处理点,有望很快扩展到Windows服务器。 可用数据的范围非常广泛,直接增加了站点可靠性工程 (SRE) 操作任务的全栈可见性。 它也自然地与解决与安全和交通管理相关的挑战相一致。 钩子的范围同样广泛,为 BPF应用提供了一系列有用的触发点,吸引了可观察性、安全性和网络专家。 BPF 是一项无需花费太多钱就能实现可观察性的正确技术。 一切都始于可观察性。

BPF 的基本设计使其成为一种尽可能高效的计算工作方法(每瓦特)。 更好的是,工具链为您生成字节码,因此您可以专注于所需的结果,而不是低级汇编语言类型的编程。 如何? 这两个设计特点使得 BPF 大放异彩:

指令集设计

BPF 的软件设计有意模仿新兴的现代 CPU 架构。 事实上,使用处理器术语是因为它准确地描述了 BPF 元素和用途。 BPF 有寄存器和指令。 它们被设计用于 CPU 直接使用。 BPF 基于 BSD 数据包过滤器设计(1992),是一种重新设计的数据包捕获过滤器机,更适合当前基于寄存器的 CPU 架构。 这种设计在 2014 年得到了自然的推动,当时 Linux内核v3.18中发布了“增强型伯克利数据包过滤器”( eBPF) 。eBPF 在发布后的早期与经典伯克利数据包过滤器(cBPF)有一个重要的区别。 如今,由于所有受支持的内核版本都包含 2014 年的增强功能,因此这种区别不再那么重要。 值得注意的是: 更宽的寄存器(从 32 位到 64 位意味着每个缓存行/时钟周期完成更多的工作),更多的寄存器(从 2 个到 10 个意味着现代 CPU 寄存器和内核 ABI 之间更多的 1 对 1 映射),以及一些额外的指令集增强功能,使 BPF 程序更安全、更有用。

链路层

BPF 由网络分接头和数据包过滤器组成。 当数据包从线路传输到指定的网络接口时,分接头在数据链路层运行。 它复制数据包供过滤器查询。 该插入点使其能够完全了解 Linux 主机的网络路径。 对于入口流量,这意味着在主机处理器开始处理它之前,而对于出口流量,这意味着在它到达网络离开主机之前。 该图显示 BPF 与数据链路层的入口数据包路径相交。

入口路径

可用数据的范围非常广泛,直接增加了 SRE 操作任务的全栈可见性。 在这个例子中,我们重点关注IPv4 标头中的一些最常用字段

入口路径

利用这些数据,可以定义策略来定制数据包过滤。 以下策略过滤发往特定目标 IP 地址的 TCP 数据包。

入口路径

利用 eBPF 实现可观察性具有 BOGO(买一送一)的好处: 观察到的数据除了用于观察之外,还可用于其他目的。 例如,流量路由或安全性。

回顾我们之前分享的数据集,用于观察 Linux 主机的流量入口路径的数据集的部分内容对于其他事情也很有用。 例如,源 IP、目标 IP、目标主机和端口对于入口流量路由和限制访问都很有用。

无论用途如何,一切都从 BPF tap 的数据包复制开始。 一旦复制完成,数据就可以放入内存(有关BPF Maps的更多信息),然后作为遥测流导出,并同时被指定策略和过滤操作的其他 BPF 程序利用。 这就是从可观察性到流量管理和安全性的分支发生的地方。 为了充分利用 BPF 的极高效率,首先要清楚了解需要什么数据以及如何使用这些数据。 在本系列的下一篇文章中,我的同事 Muhammad Waseem Sarwar 将探讨在 Linux 网络堆栈的各个位置进行 BPF 编程的选项。