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 的云原生可观测性开源工具,旨在帮忙用户更好更快的定界云原生零碎问题,并致力于打造云原生全故障域的定界能力。
退出咱们
关注咱们