将eBPF添加到商业可观察性产品是一场军备竞赛,在这篇文章中,我将描述如何快速做到这一点。这也适用于将其添加到自己的内部监控系统的人员。
人们喜欢在原型或构建 BPF 可观察性产品后向我展示他们的产品,但我经常希望在他们开始之前给他们建议。作为 BPF 可观察性的领导者,这是我在最近的谈话中一直包含的建议,现在我将其包含在这篇文章中。
首先,我知道你很忙。你甚至可能不喜欢 BPF。为了务实,我将描述如何花费最少的努力获得最大的价值。将此视为“版本 1”:一个非常有用的起点。不管你是否听从这个忠告,至少请你理解它,以免日后后悔和痛苦。
如果你使用的是开源监控平台,首先检查它是否已经有 BPF 代理。这篇文章假设它没有,你将第一次添加一些东西。
- 运行你的第一个工具
首先安装bcc或bpftrace工具。例如,在 Ubuntu 上密件抄送:
apt-get install bpfcc-tools
然后尝试运行一个工具。例如,使用 execsnoop(8) 查看带有时间戳的进程执行:
bpftrace -f json execsnoop.bt
{“type”: “attached_probes”, “data”: {“probes”: 2}}
{“type”: “printf”, “data”: “TIME(ms) PID ARGS\n”}
{“type”: “printf”, “data”: "2737 849176 "}
{“type”: “join”, “data”: “ls -F”}
{“type”: “printf”, “data”: "5641 849178 "}
{“type”: “join”, “data”: “date”}
虽然基本,但我已经单独使用这个工具解决了许多性能问题,包括配置错误的系统,其中一个 shell 脚本在循环中启动失败的进程,以及当一些小应用程序崩溃并每隔几分钟重新启动但尚未被注意到时.
2. 为您的产品添加工具
现在想象一下将 execsnoop(8) 添加到您的产品中。您可能已经在所有客户系统上运行了代理。他们有办法运行命令并返回文本输出吗?或者运行命令并将输出发送到其他地方进行聚合(S3、Hive、Druid 等)?有很多选择,根据您现有的系统和客户环境,这真的是您自己的偏好。
当您将您的第一个工具添加到您的产品中时,让它运行一小段时间,例如 10 到 60 秒。我刚刚注意到 execsnoop(8) 还没有持续时间选项,所以在此期间你可以用watch -s2 60 execsnoop-bpfcc包装它。如果您想 24x7 全天候运行这些工具,请先研究间接费用以了解成本。诸如流程执行之类的低频事件应该可以忽略不计。
除了密件抄送,您还可以使用bpftrace版本。这些通常没有固定选项(-v、-l等),但有 json 输出模式。例如:
bpftrace -f json execsnoop.bt
{“type”: “attached_probes”, “data”: {“probes”: 2}}
{“type”: “printf”, “data”: “TIME(ms) PID ARGS\n”}
{“type”: “printf”, “data”: "2737 849176 "}
{“type”: “join”, “data”: “ls -F”}
{“type”: “printf”, “data”: "5641 849178 "}
{“type”: “join”, “data”: “date”}
添加了此模式,以便可以在 bpftrace 之上构建 BPF 可观察性产品。
3.不用担心依赖
我确实建议您在客户系统上安装 bcc 或 bpftrace,它们目前具有 llvm 依赖项。这可以增加多达数十兆字节,这对于某些资源受限的环境(嵌入式)来说可能是一个问题。我们一直在做很多工作来解决这个问题。bcc 具有使用BTF 和 CO-RE(而不是 Python)的较新版本的工具(libbpf-tools),最终意味着您可以安装 100 KB 二进制版本的工具,而无需依赖。bpftrace 有一个类似的计划,即使用较新的内核功能生成一个小的无依赖二进制文件。
这确实需要至少 Linux 5.8 才能正常运行,而您的客户可能多年都不会运行它。在此期间,我建议暂时不要担心 llvm 依赖项,因为稍后会修复它。
请注意,并非所有 Linux 发行版都启用了 CONFIG_DEBUG_INFO_BTF=y,这对于 BTF 和 CO-RE 的未来是必需的。主要发行版已设置它,例如在 Ubuntu 20.10、Fedora 30 和 RHEL 8.2 中。但是,如果您知道您的一些客户正在运行一些不常见的东西,请检查并鼓励他们或发行版供应商设置 CONFIG_DEBUG_INFO_BTF=y 和 CONFIG_DEBUG_INFO_BTF_MODULES=y 以避免将来痛苦。
4. 版本 1 仪表板
现在您的产品中有一个 BPF 可观察性工具,是时候添加更多了。以下是您可以作为通用 BPF 可观察性仪表板运行和呈现的十大工具,以及建议的可视化效果:
Tool | Shows | Visualization | |
---|---|---|---|
1. | execsnoop | New processes (via exec(2)) | table |
2. | opensnoop | Files opened | table |
3. | ext4slower | Slow filesystem I/O | table |
4. | biolatency | Disk I/O latency histogram | heat map |
5. | biosnoop | Disk I/O per-event details | table, offset heat map |
6. | cachestat | File system cache statistics | line charts |
7. | tcplife | TCP connections | table, distributed graph |
8. | tcpretrans | TCP retransmissions | table |
9. | runqlat | CPU scheduler latency | heat map |
10. | profile | CPU stack trace samples | flame graph |
这是基于我的bcc Tutorial,许多也存在于 bpftrace 中。我选择这些是为了用最少的工具获得最多的性能胜利。
请注意,runqlat 和 profile 可能有明显的开销,所以我只运行这些工具 10 到 60 秒并生成报告。如果需要,一些开销足够低,可以 24x7 运行(例如,execsnoop、biolatency、tcplife、tcpretrans)。
您可以链接到 bcc 和 bpftrace 存储库中的手册页和示例文件的文档,以帮助您的客户了解工具输出。例如,这里是bcc和bpftrace中的 execsnoop(8) 示例文件。
一旦你完成了这一切,你就有了版本 1!
密件抄送与 bpftrace
密件抄送工具是最容易使用的,因为它们通常有许多命令行选项。bpftrace 工具更易于编辑和自定义,并且 bpftrace 具有 json 输出模式。
如果您完全不熟悉跟踪,请使用密件抄送。如果您想对工具进行一些修改和自定义,请使用 bpftrace。最后,它们都是不错的选择。
案例研究:Netflix
Netflix 正在基于这些工具的 bpftrace 版本构建一个新的 GUI,用于执行此工具仪表板等功能。架构是:
虽然 bpftrace 二进制文件安装在所有目标系统上,但 bpftrace 工具(文本文件)位于 Web 服务器上,并在需要时推出。这意味着我们可以通过在一个地方更新它们来确保我们始终运行最新版本的工具。
这目前是我们的 FlameCommander UI 的一部分,它还在云中运行火焰图。我们之前的 BPF GUI 是Vector的一部分,并且使用了 bcc,但我们已经弃用了它。我们可能会在某个时候开放新的源代码,并在 Netflix 技术博客上发布关于它的帖子。
案例研究:脸书
Facebook 是 BPF 的高级用户,但有关他们如何在整个车队范围内运行工具的详细信息并未完全公开。基于 bcc 中的活动,以及他们对 BTF 和 CO-RE 技术的开发,我强烈怀疑他们的解决方案是基于 bcc libbpf-tool 版本。
移植陷阱
BPF 跟踪工具类似于应用程序和内核补丁。他们需要不断更新以继续在不同的软件版本上工作。将它们移植到不同的语言然后不维护它们可能就像尝试将 Linux 4.15 补丁应用于 Linux 5.12。如果你幸运的话,它会爆炸!如果你不走运,补丁会应用,但会以一种微妙的方式破坏一些东西,直到以后你才注意到。这取决于工具。
作为一个极端的例子,我在 2014 年度假时编写了 cachestat(8),用于 Netflix 云,当时它是 Linux 3.2 和 3.13 的混合版本。这些版本中不存在 BPF,因此我使用了 Linux 3.2 上可用的基本 Ftrace 功能。我将这种方法描述为脆弱和沙堡随着内核的变化,这将需要维护。后来它通过 kprobes 移植到 BPF,现在已经被重写并包含在商业可观察性产品中。不出所料,我听说它在较新的内核上存在问题,打印输出没有意义。它确实需要大修。当我(或某人)这样做时,任何从密件抄送中提取更新的人都会自动获得固定版本,不费吹灰之力。那些已经重写它的人将需要重写他们的。我担心他们不会,而且客户会多年来一直在运行一个损坏的 cachestat(8) 版本。
请注意,如果在我编写 cachestat(8) 时 BPF 在我的目标环境中可用,那么我将对其进行完全不同的编码。人们正在移植为 Linux 3.2 编写的东西并在 Linux 5.x 上运行它。
在之前的一篇博文An Unbelievable Demo中,我谈到了很多年前类似的事情是如何发生的,在没有更新的情况下使用旧的跟踪工具版本。
我所描述的问题是特定于 BPF 软件和内核跟踪的。作为一个不同的例子,我的火焰图软件已经被重写了十几次,因为它是一个简单而完整的算法,我认为这没有什么大问题。我更喜欢人们帮助使用较新的d3 版本,但如果人们自己做这没什么大不了的。您可以对其进行编码,它将永远有效。基于 uprobe 和 kprobe 的 BPF 工具并非如此,因为它们确实需要维护。
像系统管理员一样思考,而不是像程序员一样思考
总之,首先检查您的监控系统是否已经存在 BPF 代理,如果没有,则基于现有的bcc或bpftrace工具构建一个,而不是从头开始重写所有内容。这就像安装和维护软件的系统管理员一样思考,而不是像编写所有代码的程序员一样思考。安装 bcc 或 bpftrace 工具,将它们添加到您的可观察性产品中,并根据需要提取包更新。这将是一个快速且有用的版本 1。BPF 启动并运行!
我看到人们像程序员一样思考,并且觉得他们必须从深入学习 bcc 和 BPF 编程开始。然后,在发现一切都是 C 或 Python 之后,有些人用不同的语言重写了它。
首先,学习 bcc 和 BPF 需要数周时间;了解系统跟踪的微妙之处和陷阱可能需要数月或数年。为了让您了解您的目标,请查看我的BPF Internals演讲。如果你真的想这样做并且有时间,你当然可以(你可能会在跟踪会议上遇到我:在 Linux Plumber’s 或跟踪峰会上见!)但是如果你在某个截止日期之前添加 BPF 可观察性,尝试像系统管理员一样思考,并在现有工具的基础上构建。那是快速的方法。以后像程序员一样思考,如果或当你有时间的时候。
其次,BPF 软件,尤其是某些基于 kprobe 的工具,需要持续维护。一个工具可能在 Linux 5.3 上工作,但在 5.4 上中断,因为跟踪的函数被重命名或添加了新的代码路径。BPF 库和框架也在不断变化和发展,最近得到了 BTF 和 CO-RE 的支持。这是我希望人们在选择重写它们之前考虑的问题:您是否有计划重写所有更新,或者您最终会卡在库的旧端口上?提取所有内容的更新比维护自己的版本更容易。
最后,如果你有一个比我们在 bcc 和 bpftrace 中使用的更好的 BPF 库或框架的好主意怎么办?与我们交谈,尝试,创新。我们正处于 BPF 时代的开端,还有很多东西需要探索。但请先了解存在的内容以及您所承担的维护负担。你的精力最好花在创造新事物上,而不是移植旧事物。
转载翻译自: https://www.brendangregg.com