Wasm-bpf

Wasm-bpf 是一个 WebAssembly eBPF 工具链与运行时,允许在 Wasm 中构建和运行 eBPF 程序。它结合了 WebAssembly 的跨平台性和 eBPF 的高性能,提供安全、轻量级的解决方案,适用于云原生和可观测性场景。

  • 项目地址:https://github.com/eunomia-bpf/wasm-bpf- 项目标题:Wasm-bpf:eBPF 的 WebAssembly 工具链与运行时,在 Wasm 中构建和运行 eBPF 程序- 项目描述:Wasm 最初是以浏览器安全沙盒为目的开发的,发展到目前为止,WebAssembly 已经成为一个用于云原生软件组件的高性能、跨平台和多语言软件沙箱环境,Wasm 轻量级容器也非常适合作为下一代无服务器平台运行时。另一个令人兴奋的趋势是 eBPF 的兴起,它使云原生开发人员能够构建安全的网络、服务网格和多种可观测性组件,并且它也在逐步渗透和深入到内核的各个组件,提供更强大的内核态可编程交互能力。现在,借助 Wasm-bpf 编译工具链和运行时,我们可以使用 Wasm 将 eBPF 程序编写为跨平台的模块,同时使用 C/C++ 或 Rust 来编写 Wasm-eBPF 程序并发布。通过在 WebAssembly 中使用 eBPF 程序,我们不仅能让 Wasm 应用享受到 eBPF 的高性能和对系统接口的访问能力,还可以让 eBPF 程序使用到 Wasm 的沙箱、灵活性、跨平台性、和动态加载,并且使用 Wasm 的 OCI 镜像来方便、快捷地分发和管理 eBPF 程序。结合这两种技术,我们将会给 eBPF 和 Wasm 生态来一个全新的开发体验!Wasm-bpf 是一个 WebAssembly eBPF 库和运行时, 基于 CO-RE(一次编写 – 到处运行) libbpfwasm-micro-runtime 实现。- 亮点:- 通用: 给 WASM 提供大部分的 eBPF 功能。 比如从 ring buffer 或者 perf buffer 中获取数据、 通过 maps 提供 内核 eBPF 和 用户态 Wasm 程序之间的双向通信、 动态 加载, 附加 或者 解除附加 eBPF程序等。 支持大量的 eBPF 程序类型和 map 类型, 覆盖了用于 tracing(跟踪), networking(网络), security(安全) 的使用场景。- 高性能: 对于复杂数据类型,没有额外的 序列化 开销。 通过 共享内存 来避免在 Host 和 WASM 端之间的额外数据拷贝。- 简单便捷的开发体验: 提供和 libbpf-bootstrap 相似的开发体验, 自动生成 Wasm-eBPF 的 skeleton 头文件以及用于绑定的 类型 定义。- 非常轻量: 编译完成的二进制文件只有 1.5 MB 的大小,编译好的 WASM 模块只有 ~90K ,远远比传统的以容器方式分发和运行 eBPF 程序来的轻量,同时保持良好的隔离性和沙箱特性。你可以非常容易地使用任何语言,在任何平台上建立你自己的 Wasm-eBPF 运行时,使用相同的工具链来构建应用!WASI-bpf- 演示视频:https://www.bilibili.com/video/BV1vD4y1P78S/- 示例代码:使用 C/C++ 在 Wasm 中构建 eBPF 应用,将 eBPF 字节码加载到内核并处理内核返回的对应的数据c /* 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 应用:rsextern "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 发布:bash# push to Github Packagesecli push https://ghcr.io/eunomia-bpf/sigsnoop:latest# pull from Github Packagesecli pull https://ghcr.io/eunomia-bpf/sigsnoop:latest# run eBPF programecli run https://ghcr.io/eunomia-bpf/sigsnoop:latest- 后续更新计划: - 继续完善多种语言支持; - 支持更完善的 eBPF 特性; - 探索更多的应用场景;