有时,一项很酷的技术会达到一个转折点,真正的商业需求与该技术的优势相交叉。 这使得该技术不仅可行而且实用。 伯克利数据包过滤器(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 与数据链路层的入口数据包路径相交。
利用这些数据,可以定义策略来定制数据包过滤。 以下策略过滤发往特定目标 IP 地址的 TCP 数据包。
利用 eBPF 实现可观察性具有 BOGO(买一送一)的好处: 观察到的数据除了用于观察之外,还可用于其他目的。 例如,流量路由或安全性。
回顾我们之前分享的数据集,用于观察 Linux 主机的流量入口路径的数据集的部分内容对于其他事情也很有用。 例如,源 IP、目标 IP、目标主机和端口对于入口流量路由和限制访问都很有用。
无论用途如何,一切都从 BPF tap 的数据包复制开始。 一旦复制完成,数据就可以放入内存(有关BPF Maps的更多信息),然后作为遥测流导出,并同时被指定策略和过滤操作的其他 BPF 程序利用。 这就是从可观察性到流量管理和安全性的分支发生的地方。 为了充分利用 BPF 的极高效率,首先要清楚了解需要什么数据以及如何使用这些数据。 在本系列的下一篇文章中,我的同事 Muhammad Waseem Sarwar 将探讨在 Linux 网络堆栈的各个位置进行 BPF 编程的选项。