使用cilium开发ebpf程序

使用go开发ebpf程序最常见的一个框架就是cilium。开发前需要了解ebpf,了解go语言的基础知识。

在本地安装go之后下载bpf2go

go get github.com/cilium/ebpf/cmd/bpf2go

从最简单的开发框架开始

下载示例源码

git clone https://github.com/cilium/ebpf.git

在ebpf/examples下是官方给出的开发样例,以kprobe为例:
代码结构如下

这里以.o结尾的文件都是预编译,使用命令行

go run -exec sudo ./kprobe
就可以直接运行,打印调用次数

如果使用
go clean go generate go build
就可以清除预编译然后重新执行编译
这里我们通过写一个简单的ebpf代码来看一下如何开发

首先bpf_bpfeb.go和bpf_bpfel.go文件不需要更改,属于模板文件。我们要修改的是c文件和main.go文件

首先在c文件中我们一般不需要引入头文件,项目的examples/headers里面已经预准备了头文件,在main.go的//go:generate部分会链接进来

这里的大概逻辑是使用map去存储每次我们调用bpf函数获取到的结果,在main.go中去访问这个map并打印结果或者写到日志

struct bpf_map_def SEC("maps") counting_map = { .type = BPF_MAP_TYPE_ARRAY, .key_size = sizeof(u32), .value_size = sizeof(u64), .max_entries = 1, };

这个结构体记录了key和value的对应值 首先采集到的数据通过更新或者插入写到map中然后使用sync函数同步

在main函数中有几个固定的步骤

  1. 定义要trace的内核函数名称
  2. 允许当前进程锁定内存
  3. 初始化bpfObjects并link到我们自定义的函数,link可以调用kprobe也可以调用Tracepoint,需要看个人需求。这里需要填写刚才定义的objs的自定义函数。这里需要注意,比如我在c文件中定义的函数名为handle_tp,在这里如果直接这样写会报错objs找不到这个成员函数。这里需要将函数转为驼峰写法(应该是go做过转换)。写成HandleTp就可以正常编译。
  4. 启动一个定时器,每秒去读一次map,并打印值

这里bpf_map_def结构体非常重要,他的key其实是固定的为0,当然我们可以自定义一个key值。这里map是一段共享内存可以在内核和用户空间共享

在编写好c文件和main文件之后可以调用go generate go build go run -exec sudo ./hello_world来调试查看效果

posted @   Djw945  阅读(124)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示