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/piperm...),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-p...
对于将来
随着国内3.x内核版本操作系统的逐步更新换代,Kindling有理由抉择社区热度更火、细节方面更杰出的cilium-eBPF作为底层根底库,也有理由抉择通过有数环境验证的libbcc作为底层库。总之,所有取决与Kindling用户的须要,Kindling对此呈凋谢态度并且始终权衡利弊,抉择当下最合适的计划。
Kindling是一款基于eBPF的云原生可观测性开源工具,旨在帮忙用户更好更快的定界云原生零碎问题,并致力于打造云原生全故障域的定界能力。
退出咱们
关注咱们