网络性能-ebpf

在用户协议栈领域,最好的性能优化框架是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"
相关推荐
shengjk16 分钟前
SparkSQL Join的源码分析
后端
Linux编程用C7 分钟前
Rust编程学习(一): 变量与数据类型
开发语言·后端·rust
uhakadotcom14 分钟前
一文读懂DSP(需求方平台):程序化广告投放的核心基础与实战案例
后端·面试·github
吴生43961 小时前
数据库ALGORITHM = INSTANT 特性研究过程
后端
程序猿chen1 小时前
JVM考古现场(十九):量子封神·用鸿蒙编译器重铸天道法则
java·jvm·git·后端·程序人生·java-ee·restful
Chandler241 小时前
Go:接口
开发语言·后端·golang
ErizJ1 小时前
Golang|Channel 相关用法理解
开发语言·后端·golang
automan021 小时前
golang 在windows 系统的交叉编译
开发语言·后端·golang
Pandaconda1 小时前
【新人系列】Golang 入门(十三):结构体 - 下
后端·golang·go·方法·结构体·后端开发·值传递
我是谁的程序员2 小时前
Flutter iOS真机调试报错弹窗:不受信任的开发者
后端