在 Linux Plumber 的会议上,至少有 24 场关于 eBPF 的演讲。它已迅速成为一项非常宝贵的技术,而且成为一项抢手的技能。也许你想要一个新年的决心:学习 eBPF!
eBPF 应该代表一些有意义的东西,比如虚拟内核指令集(VKIS),但由于它的起源,它是伯克利包过滤器的扩展。它可用于许多方面:网络性能、防火墙、安全性、跟踪和设备驱动程序。其中一些在线上有大量免费文档,例如用于跟踪,而另一些则还没有。跟踪一词是指可以生成每个事件信息的性能分析和可观察性工具。您可能已经使用过跟踪器:tcpdump和strace是专门的跟踪器。
在这篇文章中,我将介绍学习 eBPF 以进行跟踪,分为初学者、中级和高级用户的内容。总之:
初学者
1、什么是eBPF、bcc、bpftrace、iovisor?
eBPF 对 Linux 的作用就像 JavaScript 对 HTML 的作用一样。(有点。)因此,JavaScript 不是静态的 HTML 网站,而是允许您定义在鼠标点击等事件上运行的小程序,这些小程序在浏览器中的安全虚拟机中运行。使用 eBPF,您现在可以编写运行在磁盘 I/O 等事件上的小程序,而不是固定的内核,这些事件在内核中的安全虚拟机中运行。实际上,eBPF 更像是运行 JavaScript 的 v8 虚拟机,而不是 JavaScript 本身。eBPF 是 Linux 内核的一部分。
直接在 eBPF 中编程非常困难,就像在 v8 字节码中编码一样。但是没有人在 v8 中编写代码:他们使用 JavaScript 编写代码,或者通常是 JavaScript 之上的框架(jQuery、Angular、React 等)。eBPF 也是如此。人们将通过框架使用它并在其中编写代码。对于跟踪,主要是**bcc** 和**bpftrace** 。这些并不存在于内核代码库中,它们存在于 github 上名为iovisor 的 Linux Foundation 项目中。
2. eBPF 追踪的一个例子是什么?
这个基于 eBPF 的工具显示已完成的 TCP 会话,以及它们的进程 ID (PID) 和命令名称 (COMM)、发送和接收的字节数 (TX_KB、RX_KB) 以及以毫秒为单位的持续时间 (MS):
# tcplife
PID COMM LADDR LPORT RADDR RPORT TX_KB RX_KB MS
22597 recordProg 127.0.0.1 46644 127.0.0.1 28527 0 0 0.23
3277 redis-serv 127.0.0.1 28527 127.0.0.1 46644 0 0 0.28
22598 curl 100.66.3.172 61620 52.205.89.26 80 0 1 91.79
22604 curl 100.66.3.172 44400 52.204.43.121 80 0 1 121.38
22624 recordProg 127.0.0.1 46648 127.0.0.1 28527 0 0 0.22
3277 redis-serv 127.0.0.1 28527 127.0.0.1 46648 0 0 0.27
22647 recordProg 127.0.0.1 46650 127.0.0.1 28527 0 0 0.21
3277 redis-serv 127.0.0.1 28527 127.0.0.1 46650 0 0 0.26
[...]
eBPF没有 让这成为可能——我可以重写 tcplife 以使用旧的内核技术。但如果我这样做了,由于性能开销、安全问题或两者兼而有之,我们永远不会在生产中运行这样的工具。eBPF 所做的就是让这个工具变得实用 :它既高效又安全。例如,它不像旧技术那样跟踪每个数据包,这会增加太多的性能开销。相反,它只跟踪不太频繁的 TCP 会话事件。这使得开销如此之低,我们可以在生产环境中运行这个工具,24x7。
3. 如何使用?
对于初学者,请尝试 bcc 中的工具。请参阅适用于您的操作系统的bcc安装说明。在 Ubuntu 上,它可能是这样的:
# sudo apt-get install bpfcc-tools
# sudo /usr/share/bcc/tools/opensnoop
PID COMM FD ERR PATH
25548 gnome-shell 33 0 /proc/self/stat
10190 opensnoop -1 2 /usr/lib/python2.7/encodings/ascii.x86_64-linux-gnu.so
10190 opensnoop -1 2 /usr/lib/python2.7/encodings/ascii.so
10190 opensnoop -1 2 /usr/lib/python2.7/encodings/asciimodule.so
10190 opensnoop 18 0 /usr/lib/python2.7/encodings/ascii.py
10190 opensnoop 19 0 /usr/lib/python2.7/encodings/ascii.pyc
25548 gnome-shell 33 0 /proc/self/stat
29588 device poll 4 0 /dev/bus/usb
^C
在那里,我通过运行 opensnoop 来测试这些工具是否有效。如果你走到这一步,你已经使用了 eBPF!
默认情况下,包括 Netflix 和 Facebook 在内的公司在所有服务器上都安装了密件抄送,也许您也想这样做。
4. 有初学者教程吗?
是的,我创建了一个密件抄送教程,这是初学者进行 eBPF 跟踪的一个很好的起点:
作为初学者,您不需要编写任何 eBPF 代码。bcc 附带 70 多种工具,您可以立即使用。本教程将引导您完成其中的 11 个:execsnoop、opensnoop、ext4slower(或 btrfs*、xfs*、zfs*)、biolatency、biosnoop、cachestat、tcpconnect、tcpaccept、tcpretrans、runqlat 和 profile。
一旦你尝试了这些,你只需要知道还有更多:
这些也完全记录在手册页和示例文件中。示例文件(bcc/tools 中的 *_example.txt)显示带有解释的屏幕截图:例如biolatency_example.txt。我编写了许多示例文件(以及手册页和工具),它们就像您可以在 bcc 存储库中找到的额外 50 篇博客文章。
缺少的是生产示例。当 eBPF 很新时,我编写了所有这些文档,它只在我们的测试实例上可用,所以大多数示例都是合成的。随着时间的推移,我们将添加真实世界的示例,这是初学者可以提供帮助的领域:如果您使用工具解决问题,请考虑发布帖子以共享屏幕截图,或将其添加到示例文件中。
中间的
此时,您应该运行 bcc 并尝试了这些工具,并且您对自定义它们和编写自己的工具感兴趣。最好的方法是切换到 bpftrace,它具有更容易学习的高级语言 。缺点是它不像密件抄送那样可定制,因此您最终可能会遇到限制并想要切换回密件抄送。
请参阅bpftrace 安装说明。这是一个较新的项目,因此在撰写本文时它并未随处打包。将来,它应该只是apt-get install bpftrace或等效的。
1. bpftrace 教程
我开发了一个教程,通过一系列单行教程教授 bpftrace:
Attaching 1 probe...
181 /proc/cpuinfo
181 /proc/stat
1461 /proc/net/dev
1461 /proc/net/if_inet6
^C
那是使用打开的系统调用跟踪点来跟踪打开的 PID 和路径。
2. bpftrace 参考指南
有关 bpftrace 的更多信息,我创建了参考指南,其中包含语法、探针和内置函数的示例:
故意简洁:我尽可能将主题标题、摘要和屏幕截图全部放在一个屏幕上。如果您查找某些内容并且需要多次向下翻页,我认为它太长了。
3. bpftrace 示例
bpftrace 存储库中有 20 多个工具,您可以浏览这些工具作为示例:
例如:
# cat tools/biolatency.bt
[...]
BEGIN
{
printf("Tracing block device I/O... Hit Ctrl-C to end.\n");
}
kprobe:blk_account_io_start
{
@start[arg0] = nsecs;
}
kprobe:blk_account_io_completion
/@start[arg0]/
{
@usecs = hist((nsecs - @start[arg0]) / 1000);
delete(@start[arg0]);
}
与 bcc 一样,这些工具也有手册页和示例文件。例如,biolatency_example.txt。
高级的
1.学习bcc开发
我创建了两个文档来帮助这里:
在 bcc/tools/*.py 下也有很多例子。bcc 工具分为两部分:用于内核的 BPF 代码,用 C 编写,以及用 Python(或 lua,或 C++)编写的用户空间工具。开发 bcc 工具有些先进,可能涉及一些坚韧不拔的内核或应用程序内部。
2. 贡献
帮助表示赞赏:
对于 bpftrace,我创建了bpftrace 内部开发指南。当你在 llvm IR 中编码时会变得很困难,但如果你准备好迎接挑战…
还有内核 eBPF(又名 BPF)引擎:如果您浏览 bcc 和 bpftrace 问题,您会在那里看到一些增强请求。例如,bpftrace 内核标签。还可以查看netdev邮件列表,了解最新的内核 BPF 开发,这些开发在合并到主线 Linux 之前被添加到 net-next。
除了编写代码之外,您还可以为测试、打包、博客文章和演讲做出贡献。