我们的项目地址:https://github.com/yunwei37/Eunomia
eBPF 是一项革命性的技术,它能在操作系统内核中运行沙箱程序。被用于安全并有效地扩展内核的能力而无需修改内核代码或者加载内核模块。
但是开发、构建和分发 eBPF 一直以来都是一个高门槛的工作,社区先后推出了 BCC、BPFTrace 等前端绑定工作,大大降低了编写和使用 eBPF 技术的门槛,但是这些工具的源码交付方式,需要运行 eBPF 程序的 Linux 系统上安装配套的编译环境,对于分发带来了不少的麻烦,同时将内核适配的问题在运行时才能验证,也不利于提前发现和解决问题。
近年来,为解决不同内核版本中 eBPF 程序的分发和运行问题,社区基于 BTF 技术推出了 CO-RE 功能(“一次编译,到处运行”),一定程度上实现了通过 eBPF 二进制字节码分发,同时也解决了运行在不同内核上的移植问题,但是对于如何打包和分发 eBPF 二进制代码还未有统一简洁的方式。除了 eBPF 程序,目前我们还需要编写用于加载 eBPF 程序和用于读取 eBPF 程序产生数据的各种代码,这往往涉及到通过源码复制粘贴来解决部分问题。
Eunomia 同样基于 CO-RE(Compile Once-Run Everywhere)为基础实现,保留了资源占用低、可移植性强等优点,同时更适合在生产环境批量部署所开发的应用:
Eunomia 想要探索一条全新的路线:在本地编译或者远程服务器编译之后,使用 http RESTful API 直接进行 ebpf 字节码的分发,在生产环境最小仅需 4 MB 的运行时,约 100ms 的时间和微不足道的内存、CPU 占用即可实现 ebpf 代码动态分发、热加载、热更新,不受内核版本限制,不需要在生产环境中安装底层库(如 LLVM、python 等)、搭建环境即可启动;
从古至今,由于内核有监视和控制整个系统的特权,操作系统一直都是实现可观察性、安全性和网络功能的理想场所。同时,操作系统内核也很难进化,因为它的核心角色以及对稳定和安全的高度要求,因此,操作系统级别的创新相比操作系统之外实现的功能较少。

eBPF 从根本上改变了这个定律。通过允许在操作系统内运行沙箱程序,应用开发者能够运行 eBPF 程序在运行时为操作系统增加额外的功能。然后操作系统保证安全和执行效率,就像借助即时编译器(JIT compiler)和验证引擎在本地编译那样。这引发了一波基于 eBPF 的项目,涵盖了一系列广泛的使用案例,例如:
众所周知,计算机程序的分发也经历了几个阶段,每个阶段都会带来一次巨大的流量突破和爆发:
同样, ebpf 程序的开发和分发也经历了以下几个阶段:
int main(int ac, char **argv)
{
struct bpf_object *obj;
struct bpf_program *prog;
int map_fd, prog_fd;
char filename[256];
int i, sock, err;
FILE *f;
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
obj = bpf_object__open_file(filename, NULL);
if (libbpf_get_error(obj))
return 1;
prog = bpf_object__next_program(obj, NULL);
bpf_program__set_type(prog, BPF_PROG_TYPE_SOCKET_FILTER);
err = bpf_object__load(obj);
if (err)
return 1;
prog_fd = bpf_program__fd(prog);
map_fd = bpf_object__find_map_fd_by_name(obj, "my_map");
...
}