在用户协议栈领域,最好的性能优化框架是dpdk,而在内核协议栈领域,最好的框架就是ebpf。
自2014年,ebpf面向sdn,扩展成为一个通用的虚拟机。
- 扩展了寄存器数量
- 全新的BPF映射存储
- 单一的包过滤功能扩展到内核态函数,用户态函数,跟踪点,性能事件,安全控制
从此成为内核的一个顶级子系统,bcc, bpftrace 成为内核定于排错和跟踪的最佳实践。
eBPF无需修改内核源码和重新编译内核即可扩展内核功能。
linux 4.1 BCC 支持kprobe 和 tc。
linux 4.7 支持跟踪点、 perf事件、XDP、以及cgroups。同年 cilium发布。
2017 BPF成为内核独立子模块,支持kTLS、bpftool、libbpf。 可以用于跟踪,ddos,L4 LB。
2018 新增AF_XDP类型,发布bfptrace 和 bpffilter。
2019 新增尾调用,热更新。 Cilium 支持基于BPF的服务发现代理,可以完全替代kube-proxy。 2020 BPF新增LSM和tcp拥塞控制。 SRIOV 支持xdp。
2021 eBPF基金会chenchen管理。 cilium发部基于eBPF的service mesh。
1.1.1 ebpf程序需要事件触发才能执行
事件:
- 系统调用
- 内核调用
- 内核函数 退出
- 用户态函数 退出
- 网络事件
基于插桩
- 内核态插桩 kprobe
- 用户态插桩 uprobe

恶意代码无法通过 verifier
的校验。
- bpf程序不能无限循环、不能导致内核崩溃、必须在一段时间内执行完毕
- 只有特权进程才能执行bpf
1.1.2 bpf程序基于 bpf map进行存储
当然用户态程序可以通过bpf map进行交互
使用上的限制:
- 必须通过 verifier 校验,才可以执行
- 只能调用API中的辅助函数
- 程序栈空间较小,如果更大,就要用 映射存储
- 内核最小需要4.9, 最好是5.2以上,可支持100万条指令
2.1.1 BCC 工具一览

专门定位网络问题的镜像:hub.docker.com/r/nicolaka/...
bash
docker pull nicolaka/netshoot
3. BPF开发环境
- LLVM: 将BPF程序编译成字节码
- make: 编译
- BCC: bpf工具集
- libbpf: 与内核代码仓库实时同步
- bpftool: bpf 管理工具
bash
# uname -r
5.10.134-13.al8.x86_64
sudo yum install libbpf-devel make clang llvm elfutils-libelf-devel bpftool bcc-tools bcc-devel
# 下载
[root@iZbp180bxy2pnw55klqrwuZ ~]# ll
total 1308
drwxr-xr-x 9 root root 4096 Apr 2 06:36 libbpf-master
-rw-r--r-- 1 root root 1334612 Apr 11 09:26 libbpf-master.zip
## 我环境 git clone 有问题,所以直接下载的压缩包,并unzip
yum install -y unzip
unzip libbpf-master.zip
# 直接编译 libbpf-dev
cd libbpf-master/src/
make
# 编译安装到指定目录
PKG_CONFIG_PATH=/build/root/lib64/pkgconfig DESTDIR=/build/root make install
3.1 bpf的开发和执行过程
- c代码
- 基于LLVM编译成字节码
- 基于bfp系统调用,把字节码交给内核
- 内核验证通过过,就执行字节码,把执行状态保存到bpf map
- 用户程序基于bpf映射查询运行状态
由于我是新手,从BCC开始上手。 BCC 就是一个用于构建BPF程序的框架(库)。而且有python 接口。
bash
mkdir bcc
cd bcc
touch helloworld.c
# cat helloworld.c
int hello_world(void *ctx)
{
bpf_trace_printk("Hello, World!");
return 0;
}
基于python调用并执行
bash
# cat helloworld.py
#!/usr/bin/env python3
# 1) import bcc library
from bcc import BPF
# 2) load BPF program
b = BPF(src_file="helloworld.c")
# 3) attach kprobe
b.attach_kprobe(event="do_sys_openat2", fn_name="hello_world")
# 4) read and print /sys/kernel/debug/tracing/trace_pipe
b.trace_print()
# python3 helloworld.py
modprobe: FATAL: Module kheaders not found in directory /lib/modules/5.10.134-13.al8.x86_64
Unable to find kernel headers. Try rebuilding kernel with CONFIG_IKHEADERS=m (module) or installing the kernel development package for your running kernel version.
chdir(/lib/modules/5.10.134-13.al8.x86_64/build): No such file or directory
Traceback (most recent call last):
File "helloworld.py", line 6, in <module>
b = BPF(src_file="helloworld.c")
File "/usr/lib/python3.6/site-packages/bcc/__init__.py", line 365, in __init__
raise Exception("Failed to compile BPF module %s" % (src_file or "<text>"))
Exception: Failed to compile BPF module b'helloworld.c'
[root@iZbp180bxy2pnw55klqrwuZ bcc]# cat helloworld.py
遇到问题,可以参考该方式解决:
ruby
akshesh$ docker run -itd --name centos-ebpf centos:7.6.1810
akshesh$ docker exec -it centos-ebpf bash
root@centos-ebpf$ # From https://github.com/iovisor/bcc/blob/master/INSTALL.md#centos---source
root@centos-ebpf$ yum install -y epel-release
root@centos-ebpf$ yum update -y
root@centos-ebpf$ yum groupinstall -y "Development tools"
root@centos-ebpf$ yum install -y elfutils-libelf-devel cmake3 git bison flex ncurses-devel
root@centos-ebpf$ git clone https://github.com/iovisor/bcc.git
root@centos-ebpf$ mkdir bcc/build; cd bcc/build
root@centos-ebpf$ cmake3 ..
root@centos-ebpf$ make
root@centos-ebpf$ sudo make install
# 关键是安装开发工具
yum groupinstall -y "Development tools"