【开源自荐】Wasm-bpf:在 WebAssembly 中构建和运行 eBPF 程序的工具链与运行时

2023-12-21 523 views
1
推荐项目
  • 类别:C/Rust
  • 项目标题:在 WebAssembly 中构建和运行 eBPF 程序的工具链、库与运行时
  • 项目描述:

到目前为止,WebAssembly 已经成为一个用于云原生软件组件的高性能、跨平台和多语言软件沙箱环境,Wasm 轻量级容器也非常适合作为下一代无服务器平台运行时。 eBPF 的兴起使云原生开发人员能够构建安全的网络、服务网格和多种可观测性组件,并且它也在逐步渗透和深入到内核的各个组件中,提供更强大的内核态可编程交互能力。

借助 Wasm-bpf 编译工具链和运行时,我们可以使用 C/C++/Rust/Go 等多种语言来编写 Wasm-eBPF 程序,用 Wasm 将 eBPF 程序编写为跨平台的模块发布和运行。它可以用于任意需要 eBPF 程序动态加载、分发的场景,在边缘端或需要和大型应用集成的插件场景中会更具有优势。我们在仓库中提供的几个示例程序分别对应于可观测、网络、安全等场景。

  • 亮点:

通过在 Wasm 中构建和运行 eBPF 程序,我们不仅能让 Wasm 应用享受到 eBPF 的高性能和对系统接口的访问能力,还可以让 eBPF 程序使用到 Wasm 的沙箱、灵活性、跨平台性、和动态加载的特性,并且使用 Wasm 的 OCI 镜像来方便、快捷地分发和管理 eBPF 程序。结合这两种技术,我们将会给 eBPF 和 Wasm 生态来一个全新的开发体验!

目前没有其他将 Wasm 和 eBPF 结合起来的通用运行时与编译工具链项目。

  • 示例代码:

使用 C/C++ 在 Wasm 中构建 eBPF 应用,将 eBPF 字节码加载到内核并处理内核返回的对应的数据

    /* Load and verify BPF application */
    skel = bootstrap_bpf__open();
    if (!skel) {
        fprintf(stderr, "Failed to open and load BPF skeleton\n");
        return 1;
    }

    /* Parameterize BPF code with minimum duration parameter */
    skel->rodata->min_duration_ns = env.min_duration_ms * 1000000ULL;

    /* Load & verify BPF programs */
    err = bootstrap_bpf__load(skel);
    if (err) {
        fprintf(stderr, "Failed to load and verify BPF skeleton\n");
        goto cleanup;
    }

    /* Attach tracepoints */
    err = bootstrap_bpf__attach(skel);
    if (err) {
        fprintf(stderr, "Failed to attach BPF skeleton\n");
        goto cleanup;
    }

使用 Rust 在 Wasm 中编写 eBPF 应用:


extern "C" fn handle_event(_ctx: u32, data: u32, _data_sz: u32) {
    let event_slice = unsafe { slice::from_raw_parts(data as *const Event, 1) };
    let event = &event_slice[0];
    let pid = event.pid;
    let ppid = event.ppid;
    let exit_code = event.exit_code;
    if event.exit_event == 1 {
        print!(
            "{:<8} {:<5} {:<16} {:<7} {:<7} [{}]",
            "TIME",
            "EXIT",
            unsafe { CStr::from_ptr(event.comm.as_ptr() as *const i8) }
                .to_str()
                .unwrap(),
            pid,
            ppid,
            exit_code
        );
        ...
}

一行命令从云端的 Github Packages 中下载并运行 eBPF 程序,或通过 Github Packages 发布:

# push to Github Packages
ecli push https://ghcr.io/eunomia-bpf/sigsnoop:latest
# pull from Github Packages
ecli pull https://ghcr.io/eunomia-bpf/sigsnoop:latest
# run eBPF program
ecli run https://ghcr.io/eunomia-bpf/sigsnoop:latest
  • 截图:

WASI-bpf 演示视频:https://www.bilibili.com/video/BV1vD4y1P78S/

  • 后续更新计划:

    • 继续完善多种语言支持,以及构建和分发 eBPF 应用的工具链与运行时;
    • 支持更完善的 eBPF 特性;
    • 探索更多的应用场景;

回答