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的基础设施库来比照:
LibbccGobpfFalco-libsCilium-ebpf
开发语言c或cgogocc通过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反对的发行版本:

    发行版版本
    Ubuntu16.04+
    Debian9.0+
    RHEL7+
    CentOS7+

内核模块更杰出的性能体现(图出自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事件分类,比方该事件属于网络、文件、内存等
    FdInfoFD相干信息,比方该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的云原生可观测性开源工具,旨在帮忙用户更好更快的定界云原生零碎问题,并致力于打造云原生全故障域的定界能力。
退出咱们

关注咱们