基于eBPF的云原生可观测性开源项目Kindling之eBPF基础设施库技术选型

网友投稿 390 2022-10-06

基于eBPF的云原生可观测性开源项目Kindling之eBPF基础设施库技术选型

eBPF技术正以令人难以置信的速度发展,作为一项新兴技术,它具备改变容器网络、安全、可观测性生态的潜力。eBPF作为更加现代化的内核技术,相较于内核模块,它的编写难度已经有了较大的降低,但是不可否认对于普通开发者还是有一定门槛。因此,很多云原生软件会在eBPF系统调用(函数)和libbpf之上封装一层更加简单易用的api,比如falco的libs、bcc的libbcc、cilium的cilium-ebpf。笔者将这些依赖库称之为eBPF的基础设施。Kindling专注于云可观测性领域,致力于排查各种复杂故障,包括但不限于网络、文件、内存、on-off cpu堆栈,解决上述问题是Kindling的第一优先级目标,本着不重复造轮子的原则,Kindling无意于再创造一个eBPF的基础设施。

丰富的eBPF基础设施库

当下有很多库可以供开发者选择,比如libbcc、dropbox的goebpf、cilium的ebpf库、calico的底层库、falco的lib库。这些库主要协助完成以下功能:

将eBPF程序加载到内核中并且重定位将map载入初始化,提供fd供用户态和内核态交互更友好的开发使用体验

基于此,我们分别选择了2个基于c和go的基础设施库来对比:





Libbcc



Gobpf



Falco-libs



Cilium-ebpf



开发语言



c或cgo



go



c



c通过bpf2go转换成go



是否支持CO-RE



支持



支持



不支持(正在支持)



支持



api完善度



较好



较好



较好



很好



初始化流程完善程度










在这4个比较对象中,libbcc和gobpf一脉同源,gobpf是libbcc的go实现,其原理是用cgo包装了libbcc和libelf。faclo-libs是纯c语言的实现,cilium-ebpf则是纯go语言的实现。在功能实现方面,这些库都实现了eBPF程序加载使用的基本流程。不过这些库分别也拥有一些其独有的优势,比如:

Cilium-ebpf由于cilium踩得坑较多,在一些细节方面更加出色,比如eBPF中使用memcmp函数存在一些可用性的BUG(详见:​​https://lists.llvm.org/pipermail/llvm-bugs/2016-January/044502.html​​),cilium就重写这些基础库函数,保证函数是可用的libbcc和faclo-libs由于是纯c的库,不需要经过cgo这样的方式调用,相对来说性能也更加出色一点libbcc有更好的脚本语言生态,bcc中很多python和lua这类运行在libbcc之上的脚本已经很成熟,能帮助用户更快和更容易的写出eBPF程序

Kindling选择falco-libs的N大理由

既然基础的功能这些库都能实现,并且在细节方面cilium更加出色,那么为什么Kindling依旧选择了falco-libs作为了eBPF基础设施呢?理由如下:

对低版本内核的支持 众所周知,eBPF在4.14内核版本以上才能使用。但是现阶段很多发行版比如centOS7的内核版本都是3.x,无法使用eBPF(centOS7.6以上已经通过eBPF patch支持)。falco-libs使用内核模块实现了和eBPF相同的功能,且性能表现更加出色,Kindling认为centOS7.4等版本在国内现阶段还是广泛应用的,在低版本内核中体验到Kindling可观测性的功能是非常重要的。

由于采用了faclo-libs,Kindling支持的发行版本:

发行版

版本

Ubuntu

16.04+

Debian

9.0+

RHEL

7+

CentOS

7+

内核模块更出色的性能表现(图出自falco-libs github):

faclo社区的性能测试结果

对于系统调用的精细化整理 falco-libs是syscall方面的专家,而Kindling对syscall的分析需求也必不可少。

syscall是Kindling可观测性事件的重要来源,syscall可以分析出一次网络调用的时间、具体网络报文,一次 文件读写等指标。在Kindling的未来功能规划里,oncpu offcpu剖析也需要用到futex,write,epoll等syscall。facalo-libs梳理了300多个syscall,将其中的主要参数从内核数据结构转换成如下类似事件结构:

/* PPME_SOCKET_GETSOCKOPT_E */{"getsockopt", EC_NET, EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 0 },/* PPME_SOCKET_GETSOCKOPT_X */{"getsockopt", EC_NET, EF_USES_FD | EF_MODIFIES_STATE| EF_DROP_SIMPLE_CONS, 6, {{"res", PT_ERRNO, PF_DEC}, {"fd", PT_FD, PF_DEC}, {"level", PT_FLAGS8, PF_DEC, sockopt_levels}, {"optname", PT_FLAGS8, PF_DEC, sockopt_options}, {"val", PT_DYN, PF_DEC, sockopt_dynamic_param, PPM_SOCKOPT_IDX_MAX}, {"optlen", PT_UINT32, PF_DEC}}},/* PPME_SOCKET_SENDMSG_E */{"sendmsg", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_MODIFIES_STATE, 3, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA} } },/* PPME_SOCKET_SENDMSG_X */{"sendmsg", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_MODIFIES_STATE, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } },

Falco-libs对事件的丰富化 Falco-libs会根据内核事件的tid,fd等信息自动补全事件的以下字段:


字段



描述



Category



事件分类,比如该事件属于网络、文件、内存等



FdInfo



FD相关信息,比如该FD代表的文件,网络协议,四元组等信息



ThreadInfo



线程名称,事件所属于的容器id等信息


这让Kindling将事件转换成指标和trace变得事半功倍。

正在支持中的CO-RE Faclo-libs截止目前还未支持CO-RE,不过其已经有独立的分支开始进行相关内容支持,相信在不久的将来falco-libs将支持CO-RE。这使得笔者认为的falco-libs的最大短板将得到解决

在以上理由的驱动下,笔者认为faclo-libs是当下最适合Kindling功能需求的基础eBPF库

基于faclo-libs的拓展

由于faclo-libs专注于syscall,所以其对tracepint的支持较好,对于其他eBPF程序类型没有支持。Kindling拓展了faclo-libs的代码使其支持了kprobe

支持了centos7.6+使用eBPF拓展了除syscall之外的更多事件,并且Kindling还将根据需求不断拓展新事件,以下是Kindling已经新增的事件:

拓展了用户态动态控制probe启停的能力拓展了eBPF相关的基础函数,比如字符串比较等

这些改动都体现在该仓库agent-libs(fork on faclo/libs): ​​https://github.com/Kindling-project/agent-libs​​

对于未来

随着国内3.x内核版本操作系统的逐渐更新换代,Kindling有理由选择社区热度更火、细节方面更出色的cilium-eBPF作为底层基础库,也有理由选择经过无数环境验证的libbcc作为底层库。总之,一切取决与Kindling用户的需要,Kindling对此呈开放态度并且始终权衡利弊,选择当下最合适的方案。

Kindling是一款基于eBPF的云原生可观测性开源工具,旨在帮助用户更好更快的定界云原生系统问题,并致力于打造云原生全故障域的定界能力。

Kindling项目地址:​​Kindling​​

关注我们

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:场景实践:基于 IntelliJ IDEA 插件部署微服务应用
下一篇:Java泛型之协变与逆变及extends与super选择
相关文章

 发表评论

暂时没有评论,来抢沙发吧~