同步操作将从 openEuler/gala-gopher 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
ebpf.probe是一个bpf探针程序的开发框架,定义了一些开发规范,方便bpf程序的开发集成;
目录结构:
├── build.sh # BPF探针构建脚本
├── install.sh # BPF探针安装脚本
├── src # bpf程序源码目录
│ ├── include # 公共头文件
│ │ ├── tcp.h # TCP基础库头文件
│ │ ├── linux_4.18.0-147.5.1.6.h425.h # 内核版本的头文件(仅包含probe使用相关)
│ │ ├── linux_4.19.90-2003.4.0.0036.oe1.h # 内核版本的头文件(仅包含probe使用相关)
│ │ └── vmlinux.h -> linux_4.19.90-2003.4.0.0036.oe1.h # 根据编译环境生成的vmlinux.h
│ └── lib # 基础库
│ ├── tcp.c # TCP基础库文件
│ ├── container.c # 容器基础库文件
│ ├── xx.c # xx基础库文件
│ ├── Makefile # makefile
│ └── tcpprobe # tcpprobe探针
│ ├── tcp_link.meta # 探针数据采集meta文件
│ ├── tcpprobe.bpf.c # 探针内核BPF程序
│ ├── tcpprobe.c # 探针用户态BPF程序
│ └── tcpprobe.h # 相关头文件
│ └── xxprobe # xxprobe探针
│ ├── xx.meta # 探针数据采集meta文件
│ ├── xxprobe.bpf.c # 探针内核BPF程序
│ ├── xxprobe.c # 探针用户态BPF程序
│ └── xxprobe.h # 相关头文件
└── tools # 工具目录
├── bpftool # bpftool工具,用于生成vmlinux.h/BPF skeletons头文件
└── gen_vmlinux_h.sh # 自动生成vmlinux.h
# 环境准备(首次编译内核BPF探针时,需要构建内核头文件)
/etc/yum.repos.d/openEuler.repo
[source]
name=SOURCE
baseurl=https://repo.huaweicloud.com/openeuler/openEuler-20.03-LTS-SP2/source/
enabled=1
gpgcheck=0
[everything]
name=EveryThing
enabled=1
gpgcheck=0
baseurl=http://repo.huaweicloud.com/openeuler/openEuler-20.03-LTS-SP2/everything/x86_64/
**** 注意必须携带source源 ****
# 查看build方法
build.sh -h/--help : Show this message.
build.sh --check: Check the environment including arch/os/kernel/packages.
build.sh -g/--gen : Generate the linux header file.
build.sh -c/--clean: Clean the built binary.
build.sh -b/--build: Build all the probes.
# 生成编译环境的内核vmlinux.h头文件
build.sh -g
编程成功后可以在 gala-gopher/src/probes/extends/ebpf.probe/src/include/ 查看到具体生成的头文件
[root@master ebpf.probe]# ll src/include/
total 6404
-rw-r--r--. 1 root root 192 Oct 25 10:19 args.h
-rw-r--r--. 1 root root 16576 Oct 25 10:19 bpf.h
-rw-r--r--. 1 root root 648 Oct 25 10:19 container.h
-rw-r--r--. 1 root root 2928 Oct 25 10:19 ext_def.h
-rw-r--r--. 1 root root 1996914 Oct 25 10:19 linux_4.19.90-2012.4.0.0053.oe1.h
-rw-r--r--. 1 root root 2847 Oct 25 10:19 tcp.h
-rw-r--r--. 1 root root 1772 Oct 25 10:19 util.h
lrwxrwxrwx. 1 root root 27 Oct 25 10:19 vmlinux.h -> linux_4.19.90-2012.4.0.0053.oe1.h
**** linux_4.19.90-2012.4.0.0053.oe1.h 就是编译生成的头文件
# 编译bpf程序
[root@localhost ebpf.probe]# ./build.sh -b
# 安装bpf程序,安装到 /usr/bin/extends/ebpf.probe 目录下
[root@localhost ebpf.probe]# ./install.sh
/opt/A-Ops/gala-gopher/src/probes/extends/ebpf.probe/src/lib/util.c
.output .output/tcpprobe/ .output/killprobe/ .output/libbpf
tcpprobe/tcpprobe killprobe/killprobe /usr/bin/extends/ebpf.probe
mkdir -p /usr/bin/extends/ebpf.probe
cp tcpprobe/tcpprobe killprobe/killprobe /usr/bin/extends/ebpf.probe
[root@localhost ebpf.probe]#
# 清理编译过程
[root@localhost ebpf.probe]# ./build.sh -c
注:
bpf探针依赖libbpf开发库,./build.sh过程中会从git下载libbpf的稳定版本,编译环境要求能正常访问git;
bpf探针要求编译环境安装 elfutils-devel、clang、llvm等软件包,其中clang版本>=10.x.x,./build.sh中会检查安装;
在src目录下创建一个独立目录, Makefile中增加新的探针;
# 1 killprobe为新增的探针目录
[root@localhost src]# ll
total 20K
drwxr-xr-x. 2 root root 4.0K Apr 24 02:09 include
drwxr-xr-x. 2 root root 4.0K Apr 24 05:33 killprobe
drwxr-xr-x. 2 root root 4.0K Apr 24 05:33 lib
-rw-r--r--. 1 root root 2.7K Apr 24 03:57 Makefile
drwxr-xr-x. 2 root root 4.0K Apr 24 05:33 tcpprobe
[root@localhost src]#
# 2 Makefile中增加killprobe探针, killprobe/killprobe /前为探针目录名,/后为探针名称(编译完成后,探针名称即为执行程序名);
[root@localhost src]# vim Makefile
# add probe
APPS := tcpprobe/tcpprobe \
killprobe/killprobe \
lvsprobe/trace_lvs \
haproxyprobe/trace_haproxy \
dnsmasqprobe/trace_dnsmasq \
nginxprobe/nginx_probe \
taskprobe/taskprobe \
开发探针BPF代码,BPF源码文件名采用 探针名.bpf.c方式命名;
[root@localhost killprobe]# ll
total 1.6K
-rw-r--r--. 1 root root 1.3K Apr 24 02:09 killprobe.bpf.c
-rw-r--r--. 1 root root 294 Apr 24 02:09 killprobe.h
[root@localhost killprobe]#
#ifdef BPF_PROG_USER
#undef BPF_PROG_USER
#endif
#define BPF_PROG_KERN
#include "bpf.h" *SDK 头文件*
// kprobe/kretprobe/raw_trace 三种观测方式对应的API
#define KPROBE(func, type) // func 内核探针,BPF程序ctx类型
#define KRETPROBE(func, type) // func 内核探针,BPF程序ctx类型
#define KRAWTRACE(func, type) // func 内核探针,BPF程序ctx类型
举例:KPROBE(__x64_sys_kill, pt_regs) // 针对内核__x64_sys_kill完成kprobe方式观测
// 观测点读取参数API
PT_REGS_PARM1/2/3...6
// 内核同一个观测点,同时完成kprobe/kretprobe的API
#define KPROBE_RET(func, type)
举例:KPROBE_RET(tcp_v4_inbound_md5_hash, pt_regs) // 针对内核tcp_v4_inbound_md5_hash同时kprobe/kretprobe。
这种API一般用于观测点需要同时观测入参、返回值。
// 同时观测kprobe/kretprobe对应的读参API
#define PROBE_GET_PARMS(func, ctx, probe_val, caller_type)
#define PROBE_PARM1(probe_val)
...
...
#define PROBE_PARM5(probe_val)
PT_REGS_RC(ctx) // 读返回值
在src/.output/killprobe下;
[root@localhost killprobe]# ll
total 17.6K
-rw-r--r--. 1 root root 3.6K Apr 24 05:41 killprobe.bpf.o
-rw-r--r--. 1 root root 14K Apr 24 05:41 killprobe.skel.h
开发用户态程序;
探针用户态程序的目的是从BPF程序中获取观测数据。
[root@localhost ebpf.probe]# ll src/killprobe/
total 16K
-rw-r--r-- 1 root root 1.3K Nov 27 09:23 killprobe.bpf.c
-rw-r--r-- 1 root root 1.3K Nov 27 09:23 killprobe.c # 用户态程序
-rw-r--r-- 1 root root 274 Nov 27 09:23 killprobe.h
-rw-r--r-- 1 root root 749 Nov 27 09:23 killprobe.meta
#ifdef BPF_PROG_KERN
#undef BPF_PROG_KERN
#endif
#ifdef BPF_PROG_USER
#undef BPF_PROG_USER
#endif
#include "bpf.h" // SDK头文件
#include "XX.skel.h" // xx探针
#define LOAD(probe_name) // 加载XX探针的BPF程序
#define UNLOAD(probe_name) // 卸载XX探针的BPF程序
#define GET_MAP_OBJ(map_name) //根据MAP名称GET MAP对象
#define GET_MAP_FD(map_name) //根据MAP名称GET MAP ID
#define GET_PROG_FD(prog_name) //根据程序名称(观测点)GET PROG ID
探针框架集成探针采集数据方法
对于需要探针框架集成输出观测指标的探针,要在探针目录下增加meta元模型,定义探针输出的观测指标模型,具体方法参考如何开发探针;
在src目录下创建一个独立目录, Makefile中增加新的探针;
# 1 nginxprobe为新增的探针目录
[root@localhost ebpf.probe]# ll src/
total 48K
drwxr-xr-x 2 root root 4.0K Nov 27 09:23 dnsmasqprobe
drwxr-xr-x 2 root root 4.0K Nov 27 09:23 endpointprobe
drwxr-xr-x 2 root root 4.0K Nov 27 14:55 fileprobe
drwxr-xr-x 2 root root 4.0K Nov 27 09:23 haproxyprobe
drwxr-xr-x 2 root root 4.0K Nov 27 15:14 include
drwxr-xr-x 2 root root 4.0K Nov 27 15:12 killprobe
drwxr-xr-x 2 root root 4.0K Nov 27 09:23 lib
drwxr-xr-x 2 root root 4.0K Nov 27 09:23 lvsprobe
-rw-r--r-- 1 root root 3.0K Nov 27 09:23 Makefile
drwxr-xr-x 2 root root 4.0K Nov 27 14:33 nginxprobe
# 2 Makefile中增加nginxprobe探针, nginxprobe/nginx_probe /前为探针目录名,/后为探针名称(编译完成后,探针名称即为执行程序名);
[root@localhost src]# vim Makefile
# add probe
APPS := tcpprobe/tcpprobe \
killprobe/killprobe \
lvsprobe/trace_lvs \
haproxyprobe/trace_haproxy \
dnsmasqprobe/trace_dnsmasq \
nginxprobe/nginx_probe \
taskprobe/taskprobe \
开发探针BPF代码,BPF源码文件名采用 探针名.bpf.c方式命名;
[root@localhost ebpf.probe]# ll src/nginxprobe/
total 32K
-rw-r--r-- 1 root root 3.7K Nov 27 09:23 nginx_1.12.1.h
-rw-r--r-- 1 root root 1.2K Nov 27 09:23 nginx_link.meta
-rw-r--r-- 1 root root 4.8K Nov 27 09:23 nginx_probe.bpf.c
-rw-r--r-- 1 root root 5.0K Nov 27 09:23 nginx_probe.c
-rw-r--r-- 1 root root 864 Nov 27 09:23 nginx_probe.h
-rw-r--r-- 1 root root 2.1K Nov 27 09:23 readme.md
#ifdef BPF_PROG_KERN
#undef BPF_PROG_KERN
#endif
#define BPF_PROG_USER
#include "bpf.h" *SDK 头文件*
// uprobe/uretprobe 两种观测方式对应的API
#define UPROBE(func, type) // 用户态程序需要观测的function,BPF程序ctx类型
#define URETPROBE(func, type) // 用户态程序需要观测的function,BPF程序ctx类型
举例:UPROBE(ngx_close_connection, pt_regs) // 针对Nginx观测connection关闭行为
// 观测点读取参数API
PT_REGS_PARM1/2/3...6
// 内核同一个观测点,同时完成uprobe/uretprobe的API
#define UPROBE_RET(func, type, prog_id)
这种API一般用于观测点需要同时观测入参、返回值。
// 同时观测uprobe/uretprobe对应的读参API
#define PROBE_GET_PARMS(func, ctx, probe_val, prog_id)
#define PROBE_PARM1(probe_val)
...
...
#define PROBE_PARM5(probe_val)
PT_REGS_RC(ctx) // 读返回值
在src/.output/nginxprobe;
[root@master ebpf.probe]# ll src/.output/nginxprobe/
total 132
-rw-r--r--. 1 root root 18624 Oct 25 10:20 nginx_probe.bpf.o
-rw-r--r--. 1 root root 59988 Oct 25 10:20 nginx_probe.skel.h
开发用户态程序;
探针用户态程序的目的是从BPF程序中获取观测数据。
[root@localhost ebpf.probe]# ll src/nginxprobe/
total 32K
-rw-r--r-- 1 root root 3.7K Nov 27 09:23 nginx_1.12.1.h
-rw-r--r-- 1 root root 1.2K Nov 27 09:23 nginx_link.meta
-rw-r--r-- 1 root root 4.8K Nov 27 09:23 nginx_probe.bpf.c
-rw-r--r-- 1 root root 5.0K Nov 27 09:23 nginx_probe.c // 用户程序
-rw-r--r-- 1 root root 864 Nov 27 09:23 nginx_probe.h
-rw-r--r-- 1 root root 2.1K Nov 27 09:23 readme.md
#ifdef BPF_PROG_KERN
#undef BPF_PROG_KERN
#endif
#ifdef BPF_PROG_USER
#undef BPF_PROG_USER
#endif
#include "bpf.h" // SDK头文件
#include "XX.skel.h" // xx探针
#define LOAD(probe_name) // 加载XX探针的BPF程序
#define UNLOAD(probe_name) // 卸载XX探针的BPF程序
#define GET_MAP_OBJ(map_name) //根据MAP名称GET MAP对象
#define GET_MAP_FD(map_name) //根据MAP名称GET MAP ID
#define GET_PROG_FD(prog_name) //根据程序名称(观测点)GET PROG ID
#define UBPF_ATTACH(probe_name,proc_name,func_name,error)
#define UBPF_RET_ATTACH(probe_name,proc_name,func_name,error)
例如:
UBPF_ATTACH(nginx_probe, nginx, ngx_stream_proxy_init_upstream,ret);
UBPF_RET_ATTACH(nginx_probe, nginx, ngx_stream_proxy_init_upstream,ret);
UBPF_ATTACH(nginx_probe, nginx, ngx_http_upstream_handler,ret2);
探针框架集成探针采集数据方法
对于需要探针框架集成输出观测指标的探针,要在探针目录下增加meta元模型,定义探针输出的观测指标模型,具体方法参考如何开发探针;
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。