ebpf学习

简介: ebpf学习

WSL2搭建ebpf环境

默认情况下,由于缺少所需的内核模块,EBPF 程序不会在 WSL2 上运行。以下示例错误是
此问题的指示:
modprobe: 错误: ../libkmod/libkmod.c:586 kmod_search_moddep() 无法打开 moddep 文件 '/lib/modules/4.19.84-microso
ft-standard/modules.dep.bin'
modprobe:致命:在目录 /lib/modules/4.19.84-microsoft-standard 中找不到模块 kheaders
chdir(/lib/modules/4.19.84-microsoft-standard/build): 没有那个文件或目录

要解决此问题,您需要使用缺少的内核模块重建 WSL2 内核。以下说明适用于 Ubuntu 18.04 WSL2。

git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
cd WSL2-Linux-Kernel
sudo apt install flex bison build-essential libelf-dev libncurses-dev libssl-dev
cp Microsoft/config-wsl .config

修改.config

CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
# [optional, for tc filters]
CONFIG_NET_CLS_BPF=m
# [optional, for tc actions]
CONFIG_NET_ACT_BPF=m
CONFIG_BPF_JIT=y
# [for Linux kernel versions 4.1 through 4.6]
CONFIG_HAVE_BPF_JIT=y
# [for Linux kernel versions 4.7 and later]
CONFIG_HAVE_EBPF_JIT=y
# [optional, for kprobes]
CONFIG_BPF_EVENTS=y
# Need kernel headers through /sys/kernel/kheaders.tar.xz
CONFIG_IKHEADERS=y
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m
CONFIG_DUMMY=m
CONFIG_VXLAN=m

编译并安装内核

sudo apt install dwarves
export KERNELRELEASE=$(uname -r)
make KERNELRELEASE=$KERNELRELEASE -j 4
make KERNELRELEASE=$KERNELRELEASE modules -j 4
sudo make KERNELRELEASE=$KERNELRELEASE modules_install 
ls /lib/module/$(uname -r)
sudo mount -t debugfs debugfs /sys/kernel/debug

cd ./WSL2-Linux-Kernel-linux-msft-wsl-5.10.102.1/tools/bpf/bpftool
make
make install

安装bpf

sudo apt install bpfcc-tools

执行命令验证是否安装成功

execsnoop-bpfcc
sudo apt-get install -y make gcc libssl-dev bc libelf-dev libcap-dev \
  clang gcc-multilib llvm libncurses5-dev git pkg-config libmnl-dev bison flex \
  graphviz

编译bcc

git clone https://github.com/iovisor/bcc.git
cd bcc
git submodule update --init 
mkdir /opt/bcc
cmake .. -DCMAKE_INSTALL_PREFIX=/usr
make -j4
make install

bpftrace

安装

对于 Ubuntu 19.04+、RHEL8+ 等系统,你可以直接运行下面的命令来安装 bpftrace:

# Ubuntu19.04+
apt install bpftrace
# RHEL8/CentOS8sudo 
dnf install -y bpftrace

而对于其他旧版本的系统或其他的发行版,你可以通过源代码编译的形式安装。至于具体的步骤,你可以参考它的安装文档,这里我就不展开讲了。

安装好 bpftrace 之后,你就可以执行 bpftrace -l 来查询内核插桩和跟踪点了。比如你可以通过以下几种方式来查询:


# 查询所有内核插桩和跟踪点
sudo bpftrace -l

# 使用通配符查询所有的系统调用跟踪点
sudo bpftrace -l 'tracepoint:syscalls:*'

# 使用通配符查询所有名字包含"execve"的跟踪点
sudo bpftrace -l '*execve*'

Ubuntu编译安装

sudo apt-get install -y libbpfcc-dev

sudo apt-get update
sudo apt-get install -y \
  bison \
  cmake \
  flex \
  g++ \
  git \
  libelf-dev \
  zlib1g-dev \
  libfl-dev \
  systemtap-sdt-dev \
  binutils-dev \
  libcereal-dev \
  llvm-12-dev \
  llvm-12-runtime \
  libclang-12-dev \
  clang-12 \
  libpcap-dev \
  libgtest-dev \
  libgmock-dev \
  asciidoctor
git clone https://github.com/iovisor/bpftrace
mkdir bpftrace/build; cd bpftrace/build;
../build-libs.sh
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j8
sudo make install

bpftrace默认安装到/usr/local/bin/bpftrace,工具默认位置 /usr/local/share/bpftrace/tools,可以通过使用-DCMAKE_INSTALL_PREFIX=/usr/local​改变安装位置。

问题

No such file or directory: /sys/kernel/debug/tracing/available_filter_functions

bpftrace -l
software:alignment-faults:
software:bpf-output:
software:context-switches:
software:cpu-clock:
software:cpu-migrations:
software:dummy:
software:emulation-faults:
software:major-faults:
software:minor-faults:
software:page-faults:
software:task-clock:
hardware:backend-stalls:
hardware:branch-instructions:
hardware:branch-misses:
hardware:bus-cycles:
hardware:cache-misses:
hardware:cache-references:
hardware:cpu-cycles:
hardware:frontend-stalls:
hardware:instructions:
hardware:ref-cycles:
No such file or directory: /sys/kernel/debug/tracing/available_filter_functions

原因:需要挂载debugfs

sudo mount -t debugfs debugfs /sys/kernel/debug

使用

bpftrace 的一个核心概念是探针点,即 eBPF 程序可以连接到的(内核或用户空间的)代码中的测量点,可以分成以下几大类:

kprobe——内核函数的开始处 kretprobe——内核函数的返回处 uprobe——用户级函数的开始处 uretprobe——用户级函数的返回处 tracepoint——内核静态追踪点 usdt——用户级静态追踪点 profile——基于时间的采样 interval——基于时间的输出 software——内核软件事件 hardware——处理器级事件
所有可用的 kprobe / kretprobe、tracepoints、software 和 hardware 探针可以通过这个命令列出:

 sudo bpftrace -l

uprobe / uretprobe 和 usdt 是用户空间探针,专用于某个可执行文件。

通过 bpftrace 过滤语法使用 PID 过滤出某个特定进程调用的系统调用:

sudo bpftrace -e 't:syscalls:sys_enter_* / pid == 1234 / { @[probe] = count(); }'

分析每个进程正在写的字节数:

 sudo bpftrace -e 't:syscalls:sys_exit_write /args->ret > 0/ { @[comm] = sum(args->ret); }'

bpftrace 连接操作块到写系统调用的返回探针(t:syscalls:sys_exit_write),然后使用过滤器丢掉代表错误代码的负值(/arg->ret > 0/)。

映射的键 comm 代表调用系统调用的进程名;内建函数 sum() 累计每个映射项或进程写的字节数;args 是一个 bpftrace 内建指令,用于访问追踪点的参数和返回值。如果执行成功,write 系统调用返回写的字节数,arg->ret

用于访问这个字节数。

参考资料

github

手册页

参考指南

教程

超好用的 Linux 性能工具:bpftrace
Installing bcc

Enable EBPF on WSL2

相关文章
|
存储 Rust 安全
服务网格eBPF应用探索之(一)eBPF基础知识
1)技术背景在eBPF诞生之前,对内核的调试和开发有着相当高的门槛,不仅要十分熟悉庞大的内核代码及开发流程,同时重新编译内核后若希望生效还需要重启OS,开发效率也相当低下。而eBPF提供了相当友好的内核开发/观测机制,即:由用户编写符合一定规范的代码,编译后加载至内核,内核会在指定的时机执行这段代码,内核同时还会将Hook点相关的上下文传递给这段代码供使用,代码可以修改上下文,或是通过返回值来改变
850 0
服务网格eBPF应用探索之(一)eBPF基础知识
|
2月前
|
Linux 编译器 API
eBPF技术学习
eBPF技术学习
|
3月前
|
安全 Linux 编译器
全面介绍eBPF-概念
全面介绍eBPF-概念
88 1
|
6月前
|
Linux 编译器 Shell
eBPF动手实践系列三:基于原生libbpf库的eBPF编程改进方案
为了简化 eBPF程序的开发流程,降低开发者在使用 libbpf 库时的入门难度,libbpf-bootstrap 框架应运而生。本文详细介绍基于原生libbpf库的eBPF编程改进方案。
|
6月前
|
存储 安全 编译器
eBPF是如何工作的
【2月更文挑战第1天】
|
监控 Kubernetes 网络协议
DoorDash 基于 eBPF 的监控实践
DoorDash 基于 eBPF 的监控实践
192 0
|
存储 缓存 监控
深入浅出 eBPF 技术
1 eBPF 介绍eBPF 是革命性技术, 起源于 linux 内核, 能够在操作系统内核中执行沙盒程序。旨在不改变内核源码或加载内核模块的前提下安全便捷的扩展内核能力。1.1 demo 展示demo程序如下:#include <linux/bpf.h> #define SEC(NAME) __attribute__((section(NAME), used)) SEC(&quot
3237 0
深入浅出 eBPF 技术
|
监控 安全 网络协议
eBPF 是用来干什么的?
eBPF 是用来干什么的?