目录
ebpf, libbpf 和libbpf-bootstrap/其他脚手架 之间的关系
概念介绍
bpf
ebpf
- 它提供了一个功能强大的虚拟机,在内核中执行用户定义的程序
- 通过 eBPF,用户可以编写并在内核中动态加载运行自定义的程序,而无需修改/重新编译内核源代码,从而实现了一种灵活而安全的内核扩展方式
eBPF 虚拟机
- eBPF 虚拟机提供了类似于系统调用的机制,允许用户通过 eBPF 和用户态通信的方式获得对内核的完整控制权
- 用户编写的 eBPF 程序以字节码的形式加载到内核中,并由 eBPF 虚拟机执行,就像用户态执行系统调用一样
- 所以,当今的 Linux 内核正在向一个新的内核模型演化:用户定义的应用程序可以在内核态和用户态同时执行
- 通过特定的用户态工具或接口,将eBPF程序加载到内核中的特定区域,并在不再需要时将其从内核中移除
- 我理解的他们之间的关系也许是:
- 这样各是各的,互不影响
应用
从前我们想要改变内核行为/让用户编写程序在内核中运行,只有两种方式
- 修改内核源代码,提交给社区让他们采纳
- 编写内核模块,手动加载和卸载,还要定期维护和面临未知的安全问题(因为会受到linux内核代码改变的影响)
但有了ebpf后,不需要通过改变源码来改变内核行为
当然,为了实现
eBPF 被广泛用于各类场景:
- 在现代数据中心和云原生环境中,可以提供高性能的网络包处理和负载均衡
- 以非常低的资源开销,做到对多种细粒度指标的可观测性,帮助应用程序开发人员跟踪应用程序,为性能故障排除提供洞察力
- 保障应用程序和容器运行时的安全执行
libbpf
对bpf syscall(系统调用) 做出了基础封装,提供了 open, load, attach, maps操作, CO-RE等功能
ebpf, libbpf 和libbpf-bootstrap/其他脚手架 之间的关系
引入
因为libbpf库的使用很有难度,所以现阶段的ebpf程序开发大多基于一些工具:
介绍
类似于在c语言中的系统调用,c库,第三方库之间的关系
- ebpf 提供底层接口,让用户程序可以在内核中动态执行
- 而libbpf 是用户态的c库,它对ebpf程序的接口和函数进行了封装,减少了我们的使用成本
- libbpf-bootstrap 是一个辅助工具和示例代码集合,他是使用者自己开发的一种工具,帮助我们更好地使用libbpf
- (而且还有其他很多工具供我们使用,比如eunomia-bpf和bpftime等等,他们都是ebpf的一种扩展)
libbpf-bootstrap骨架
基于 libbpf 开发出来的eBPF工具,它通过封装抽象屏蔽了很多细节
比如,通过bpftool工具直接生成用户层代码操作接口,极大减少开发人员的工作量(但是也造成用户层代码无法进行复用,因为每个函数名都是独立的)
如何安装
首先需要linux环境+11版本及以上的clang编译器
- 最好使用ubuntu环境,centos提供的软件包版本太低了
- ubuntu可以指定安装clang版本(注意更新一下软件包,但默认还是下载的clang10),但centos好像需要自己下载源码编译
然后根据libbpf-bootstrap 开发指南:概念与如何安装-CSDN博客进行环境搭建即可
源码目录
eunomia-bpf
介绍
是一个开源的 eBPF 动态加载运行时和开发工具链,是为了简化 eBPF 程序的开发、构建、分发、运行而设计的,基于 libbpf 的 CO-RE 轻量级开发框架
安装
安装llvm
sudo apt install clang llvm
安装ecc
wget https://aka.pw/bpf-ecli -O ecli && chmod +x ./ecli
安装至全局
sudo cp ecc /usr/local/bin sudo cp ecli /usr/local/bin
拉取项目源码
git clone https://github.com/eunomia-bpf/eunomia-bpf
编译和运行程序
sudo ecc xxx.bpf.c (xxx.h)
sudo ecli run package.json
bpftime
介绍
在以内核为中心的操作中,eBPF 的 uprobe 组件经常遇到性能瓶颈,这主要是因为上下文切换承担的开销
- 如果将 eBPF 操作过渡到用户空间,就可以绕过这些障碍,从而优化性能
- 这也增强了可配置性,并消除了对内核 eBPF 的 root 访问或特权的必要,从而最大限度地减少了内核攻击面
如何安装
安装环境
sudo apt-get update && sudo apt-get install \ libelf1 libelf-dev zlib1g-dev make cmake git libboost1.74-all-dev \ binutils-dev libyaml-cpp-dev ca-certificates clang llvm pkg-config llvm-dev
- 注意不是越新越好(我注意到有人反馈了这样的问题):
- 所以不要直接安装,我这里是clang14,gcc12(仅作参考)
- 这玩意很依赖环境,我装了很久才好(感觉是因为我虚拟机哪有问题,clang一会有一会没有的,而且老是变版本,我感觉最好还是先把其他版本的卸载掉,然后再装)
- 并且要注意环境变量/符号链接的设置,直接搜教程即可
- 如果是ubuntu23/20的,可以参考官方给出的版本要求:
拉取仓库源码
git clone https://github.com/eunomia-bpf/bpftime cd bpftime git submodule update --init --recursive //拉取子目录,这一步一定不能出错,不然可能会有哪些文件没下载完成,导致没法正常运行
编译
- 只要这一步成功了,基本就没啥问题了
make release JOBS=$(nproc)
- 如果失败了,可以考虑重拉项目/重新执行上述步骤(我不知道重复了这个过程多少次,麻了)
添加环境变量
export PATH=$PATH:~/.bpftime
- 但这一步对我没啥用(可以使用bpftime命令来查看是否设置成功):
- 发现没效果后,我查了查bpftime文件:
第一个是bpftime目录
第二个是可执行文件:
- 执行后成功出现提示信息,说明我们执行成功:
第三个也是一个可执行文件:
- 注意它是在根目录下的文件,所以需要root权限
- (是我们刚刚通过设置环境变量创建的?还是本来就有?这个我没验证,实在不敢重来一次,我怕又出问题)
- 执行后,也是一样的效果:
所以我这里是添加全局命令后失效,但直接运行可执行还是可以的
- 所以,可以考虑添加一个符号链接,方便我们运行
- (当然这不是什么高明的做法,大家有什么更好的解决方法吗(瘫))
ebfp程序通用数据流程
虽然说是通用,但在一些工具的开发中,可能会对此过程进行一些改动
文字介绍