BPF和eBPF是什么?
简单来说, BPF提供了一种在和各种内核和应用程序事件发生时运行一段小程序的机制
BPF是一项灵活而高效的技术, 由指令集, 存储对象和辅助函数等几部分组成,由于它采用了虚拟指令集规范, 因此也可将它视作一种虚拟机的实现. 这些指令由Linux内核的BPF运行时模块执行. 具体来说, 它运行时提供两种机制:一个解释器和一个将BPF指令动态转换为本地化指令的即时(JIT)编译器. 在实际执行之前, BPF指令必须通过验证器(Verifer)的安全性检查, 以确保BPF程序自身不会崩溃或者损坏内核.
主要作用:跟踪, 嗅探, 采样, 剖析和可观察性
BCC, bptrace和IO Visor
直接通过BPF指令编写BPF程序是非常繁琐的, 因此, 我们开发了可以提供了高级语言编程支持的BPF前端; 在跟踪用途方面, 主要的前端的是BCC和bpftrace
- BCC(BPF编译器集合, BPF Complier Collection)是最早用于开发BPF跟踪程序的高级框架, 是libbcc和libebf库的前身. BCC提供了一个编写内核BPF程序的C语言环境, 同时还提供了其他高级语言(如Python, Lua, C++)环境来实现用户端接口
- bpftarce是一个新近出现的前端, 它提供了专门用于创建的BPF工具的高级语言支持, 鱼鱼libbcc和libbpf库来进行构建的
bpftrace在编写功能强大的单行程序, 短小的脚本方面甚为理想; BCC则更为适合开发复杂的脚本和作为后台进程使用, 他们不在内核代码仓库中, 而是属于GitHub山过得一个名为IO Visor的linux基金会项目
动态插桩: kprobes和uprobes
在生产环境中对正在运行的软件插入观测点的能力
静态插桩: tracepoint和USDT
静态会将稳定的事件名字编码到软件代码中, 由开发者维护. 避免函数的接口变化或者函数内联问题导致的错误
一个推荐的策略是, 首先尝试使用静态跟踪技术(跟踪点或者USDT)
安装BCC
sudo apt-get install arping bison clang-format cmake dh-python \
dpkg-dev pkg-kde-tools ethtool flex inetutils-ping iperf \
libbpf-dev libclang-dev libclang-cpp-dev libedit-dev libelf-dev \
libfl-dev libzip-dev linux-libc-dev llvm-dev libluajit-5.1-dev \
luajit python3-netaddr python3-pyroute2 python3-distutils python3
git clone https://github.com/iovisor/bcc.git
mkdir bcc/build
cd bcc/build/
cmake ..
make
sudo make install
cmake -DPYTHON_CMD=python3 .. # build python3 binding
pushd src/python/
make
sudo make install
popd
llvm
LLVM编译器支持将BPF作为编译目标体系结构. BPF程序可以使用LLVM支持的更高级语言编写. 比如C语言(借助Clang)或LLVM中间表示形式, 然后再编译成BPF. LLVM自带一个优化器, 可以对它生成的BPF指令进行效率和体积上的优化.
编写第一个ebpf程序
from bcc import BPF
BPF(text='int kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; }').trace_print()