当前位置: 首页 > Linux

eunomia-bpf项目是开源的!eBPF轻量级开发框架来了

时间:2023-04-06 11:35:46 Linux

近日,在‖2022云栖大会龙蜥峰会eBPF&LinuxStabilitySession上,来自eBPF技术探索SIGMaintainer和浙江大学的郑雨生分享了《eunomia-bpf:eBPF 轻量级开发框架》技术演讲,如下本篇内容致辞:大家好!我是浙江大学的郑雨生。今天介绍一下eunomia-bpf项目的背景和目标,作为一个轻量级的eBPF开发框架,旨在简化eBPF程序的开发、分发和运行;并通过一些简单的例子,展示了eunomia-bpf如何通过一行命令从云端下载并运行eBPF程序,仅通过编写内核态代码即可运行和导出事件,并与WebAssembly集成。最后简单说明一下eunomia-bpf的原理和设计实现的思路,讨论一下未来的发展方向。eunomia-bpf项目龙蜥社区开源库:https://gitee.com/anolis/eunomia总结eunomia-bpf起源于2022年全国大学生操作系统大赛,希望将eBPF程序作为服务来运行,将eBPF程序打包成JSON对象可以通过HTTP请求动态地插入和运行任何可重定位的eBPF程序,并且可以适应不同的内核版本和架构。比赛结束后,在几位高校老师和社会各界小伙伴的帮助和指导下(在此感谢西安邮电大学陈立军教授及其团队和龙里大学毛文安老师)社区),逐渐将这些想法变成了一个初出茅庐的开源项目。目前eunomia-bpf要解决的问题或者说目前eBPF程序开发和分发过程中的痛点主要有以下两点:第一,对于新手来说,eBPF程序构建和开发的门槛比较高。同时注意内核态和用户态的交互和信息处理,也需要编写用户态加载代码。其次,无法在不同架构的不同内核版本上方便快捷地打包、分发和发布各种eBPF程序。很多eBPFgadget是用不同的语言开发的,有不同的接口,不能很容易地集成到大型可观察系统中。目前没有好的插件解决方案。在很多情况下,必须重新编译整个可观察框架,然后重新部署以更新eBPF探针或数据处理模块。另外,如果引入第三方用户态数据处理代码,代码崩溃会导致整个程序崩溃。因此,针对以上两个问题,我们提出了三种解决方案:1、对于初学者,只需要编写内核态代码,自动获取内核态导出的数据,编译后加载运行,减少eBPF减少学习成本,提高开发效率。2、基于libbpf一次性编译随处运行的特性,将用户态和内核态的编译运行完全分离,通过标准的JSON或WASM模块分发,无需重新编译。应用程序启动占用资源少,耗时少。甚至容器启动??时间也更短。WebAssembly(简称WASM)是一种基于堆栈虚拟机的二进制格式。WASM专为便携式目标而设计。可作为C/C+/RUST等高级语言的编译目标,使客户端和服务器应用程序能够部署在Web上。到目前为止,WASM已经发展成为一个轻量级、高性能、跨平台、多语言的软件沙箱环境,应用于云原生软件组件,可以在非浏览器环境中运行。WASM和eBPF的设计思想也有很多相似之处。3、只写内核态代码时,使用JSON完成分发、加载、打包的过程。对于完整的需要用户态和内核态交互的eBPF应用或工具,复杂的用户态可以在WASM中编写处理程序进行控制和处理,并将编译好的eBPF字节码嵌入到WASM模块中进行分发,并动态加载运行。在目标机器上。结合WASM生态项可以为eBPF程序带来很多特性,也与eBPF程序最初的设计思想如可移植性、隔离性、安全性不谋而合。它还是跨语言、轻量级运行环境等。同时,eBPF程序的OCI镜像的存储和分发也可以借助WASM相关工具完成。最近,Docker正式推出了基于WASM的分发工具。以上三部分是eunomia-bpf的核心特性,接下来就和大家一起看一些例子吧。示例eunomia-bpf并不是一个完整的系统,而是类似于一个开发库和开发框架,可以方便的嵌入到Coolbpf工具链中,也可以作为开发库或开发框架嵌入到其他程序中。可以直接从网页上单行命令下载预编译好的eBPF程序并运行。使用WebAssembly或JSON模块进行分发,部署时无需重新编译,启动速度非常快。eunomia-bpf适用于通用和任意类型的eBPF程序,不仅限于trace中的kprobe、uprobe、fentry等,还支持lsm、tc、xdp等类型的eBPF应用,你只需要编写内核模式代码完成。上图是放入URL的形式,也可以换成OCI镜像或者Docker镜像,存放在Docker仓库或者github包中。可以push编译好的包,直接使用。与传统的Docker镜像相比,它的启动速度更快,同时也保留了eBPF的重要特性,可以方便的作为子模块或插件嵌入到其他程序中。使用eunomia-bpf,只需要编写内核态代码就可以正确运行,可以最大程度地减少初学者的门槛,省去了用户态加载框架的编写,并且可以自动导出内核态perf事件或ringbuffer事件。另外,完全兼容原生libbpf,无需修改任何代码即可获取libbpf工具的内核态代码,可直接运行。可以添加额外的tracepoints,也可以通过注释的形式添加其他内容。使用容器打包编译工具链,无需担心环境配置问题。一行命令生成工程模板,一行命令编译。一般来说,一个完整的eBPF应用程序分为两部分:用户空间程序和内核程序。用户空间程序负责将BPF字节码加载到内核中,或者读取内核返回的统计信息或事件详情,并进行相关的数据处理和控制。我们可以在WASM中编写用户态辅助程序,完成安全高效的用户态数据处理和控制逻辑。它还具有eBPF的特性,比如安全性(WASM和eBPF一样也是沙盒环境,运行在用户态即使WASM模块崩溃,也不会导致宿主程序异常退出)、可移植性、轻量级、模块化、等,也可以作为插件使用,添加新的数据处理逻辑时无需改动原有代码。(注意WASM是可选的,但不是必须的,对于一些简单的应用,写内核态代码就够了。)其实我们是用C语言写代码,然后打包生成WASM模块。之后,我们可以:借助WebAssembly相关生态帮助分发和管理eBPF程序,例如docker-wasm。可以作为eBPF可编程模块或插件嵌入到大型应用程序中。这里演示的是一个简单的WASM模块,可以获取当前系统进程之间通过signal信号传递的事件,也可以接受一些命令行参数,并对上报的信息进行处理。目前我们基本可以将BCC/libbpf-tools中的程序编译成WASM模块,无需任何代码修改。在开发体验上,也可以和使用C语言开发libbpf的eBPF程序完全一样,然后也可以引入其他语言的开发SDK。WASM和eBPF结合的主要难点在于WASM的内存布局与eBPF程序不同,C语言的结构不能直接映射,因此必须对传输结构进行序列化。同时WASM对访问系统资源也有很多限制,比如文件、网络等,缺少很多标准库,所以我们需要在WASM模块中进行一些特殊的处理和移植。系统架构的底层依赖于内核态和用户态的基础设施,比如Kernel中的libbpf库和eBPF虚拟机。在内核基础设施之上,我们将提供相关的编译工具链和相应的运行时加载器,以帮助生成JSON或将它们打包到WASM模块中。工具链本身使用Clang/LLVM和bpftool等工具。动态加载库可以独立使用,与WASM无关。还可以通过动态加载JSON配置信息,以eBPF程序的形式实现热插拔和热更新,通过API接口可以轻松实现内核函数即服务(kernelfunctionasaservice)。我们还实现了WASM抽象层,包含了API规范,比如用于扩展WASM的虚拟机WSAI系统来占用eBPF或者与eBPF交互的访问形式。还有基于WASM定制的libbpf库、移植的辅助状态程序、序列化库等,用于在WASM模块中加载基于libbpf的eBPF程序。运行时库可以很容易地替换,比如WSI的WASM运行时。此外,上层还实现了LMP项目中的eBPFhub等包管理和分发设施,以及其他命令行工具和可观察性工具。目前,eunomia-bpf项目已经在DragonLizard社区开源。欢迎开发者前来体验,也欢迎大家提出建议和反馈,共同做大做强。相关链接:eunomia-bpf项目地址链接:https://github.com/eunomia-bpf/eunomia-bpfeBPF技术探索SIG地址:https://openanolis.cn/sig/ebpfresearch原文链接本文为原创内容阿里云原创,未经允许不得转载。