在去年的 linux Plumber大会上,eBPF成了亮点,至少有24个议题都提到eBPF的。在之前的关于linux新内核的文章中,虫虫也介绍过它。可以预计eBPF将成为一个新的技术趋势, 做为 一个追求新技术的你,可能不愿意错过这个潮流。那么请追随虫虫,我们一起来学习eBPF技术,将它 作为 我们2019年的第一个学习目标。
eBPF包含了许多非常有意义的软件,比如虚拟内核指令集(VKIS)。尽管它起源于Berkeley Packet Filter,是一个网络包过滤软件,但是在linux新内核中对其做了很多扩展和优化。目前它可用于方方面面:网络性能,防火墙,安全性,跟踪和设备驱动等等。eBPF一些用途有很多在线的免费文档,比如跟踪,而其他方面的功能和文档还待完善。本文中就以跟踪介质实例介绍eBPF的技术,如果使用 tcpdump 和strace,那么对于eBPF那么也很容易上手。
eBPF 介绍
eBPF是最新加入linux内核模块,上面咱们提到了他是源于BPF的网络包过滤,但是进化到eBPF后,加入了 JIT (Just-In-Time),使得它实际上成了一个虚拟机。现在通过使用eBPF,我们可以编写在磁盘I/O等事件上运行的迷你程序,这些事件执行时候可以通过在内核中的eBPF虚拟机动态执行。
eBPF 程序支持自己的 字节码 语言,基于该字节码语言编译成内核原生代码,就像 BPF 程序一样。
eBPF在内核中运行。
eBPF 程序对内核内存访问是有限制的。只能通过内核提供的函数去获取严格限制的必须的内存。
eBPF可以和User空间的程序通过 BPF Map进行通讯。
目前支持eBPF字节码的编译器只有llvm,即便是 gcc 编译过的内核bpf的范例调用也要通过llvm编译后才能执行。直接对eBPF编程还非常困难(C,llvm),为了便于使用,出现了很多eBPF框架便于我们使用。对系统追踪方面目前主要应用框架有bcc和bpftrace。目前这些框架还都需要自己手动安装配置,其源码托管 github 上iovisor用户Linux Foundation的下。
eBPF追踪实例
下面是一个eBPF追踪工具,利用该工具可以显示显示已完成的TCP会话,包括进程ID( PID )和指令名称(COMM),发送和接收的字节(TX_KB,RX_KB)以及持续时间(以毫秒为单位)(MS):
bcc工具的使用
作为初学,我们从使用 bcc工具集开始。关于bcc安装,请参考官方的bcc安装说明,注意eBPF是基于比较新的内核,在老版本或者一些追求稳定的版本是不支持的。我们以Ubuntu为例,安装很简单:
sudo apt-get update
sudo apt-get install bpfcc-tools
sudo /usr/share/bcc/tools/pensnoop
我们通过运行opensnoop来测试工具测试bcc工具是否安装好了。如果工具执行正常,那么恭喜你,你已经在使用eBPF了。
初学者教程
作为初学者,我们不需要编写任何eBPF代码。 bcc附带70多种工具,我们可以立即使用和联系。其中最常用的有:execsnoop,opensnoop,ext4slower(或btrfs *,xfs *,zfs *),biolatency,biosnoop,cachestat,tcpconnect,tcpaccept,tcpretrans,runqlat和profile。
下面是bcc追踪工具的一个应用示意图,估计很多人都见到过该图,但是多数都没有尝试使用过,那么从现在开始就应该开始使用起来:
在官方的repo仓库中有完整的使用手册页和示例文件,还有详细的范例截图。