Solo.io, a service mesh provider, recently announced an open-source project called BumbleBee. It aims to simplify eBPF application development through auto-generated templates and boilerplate files. BumbleBee provides "rails" to support development efforts along with a Docker-like experience.
The eBPF technology allows developers to enhance Linux kernels with custom logic. One common use case is for network monitoring and management. It is increasingly being used in sidecar proxies and service mesh data planes. However, creating and deploying eBPF applications remains challenging for most developers. The developer needs to create a kernel program in languages like C or Rust, compile it to eBPF using specialized compilers, deploy it into the Linux kernel of the target machine, and then create another application in the user space to interact with the eBPF program in the kernel.
With a complex technology stack like eBPF, a proven approach for onboarding new developers is to provide "rails" (or opinionated archetypes) that automate most of the boilerplate code. New developers just need to write a few lines of code on the critical path and let the tool or framework generate the entire application.
Idit Levine, CEO of Solo.io, said:
"At Solo.io, we see eBPF as a critical enabling technology that will improve application networking. We’ve been working during the last year to leverage eBPF technology with Gloo Mesh, our Istio-based service mesh offering for the enterprise. While developing eBPF extensions, we have faced many technical challenges — and this led us to develop BumbleBee to help streamline our eBPF efforts. Since we truly believe in the benefits of eBPF, we are happy to share BumbleBee with the community to accelerate eBPF adoption."
BumbleBee does exactly that. It enables the developer to write the core eBPF code in C, and then auto-generate the rest of the application including tools to deploy the code into the kernel and even a user-space UI that interacts with the eBPF program. BumbleBee grows from Solo.io’s internal development effort on building eBPF programs.
BumbleBee leverages a containerized build environment to offer a familiar and consistent developer experience. With BumbleBee tools, developers can build an eBPF program to an ELF file, then package the ELF file together with its eBPF deployment tools and auto-generated user-space application in an OCI container image. Developers could then pull the container image, deploy the eBPF program in the image to the kernel, and interact with it through the user-space application. Furthermore, developers could run eBPF programs in any containerized environment, such as in K8s clusters.
For developers, BumbleBee offers a Docker-like experience. A developer simply uses CLI tools such as bee init
, bee build
, and bee run
to create a new eBPF program, build the eBPF program into an OCI image, and run this OCI image of the eBPF program. For example, in the init
step, the developer answers four questions in terms of what type of eBPF program they want to build, and it will generate the eBPF program source code. For example, the generated code for a C program for a network probe that prints the log to the console looks like this:
#include "vmlinux.h"
#include "bpf/bpf_helpers.h"
#include "bpf/bpf_core_read.h"
#include "bpf/bpf_tracing.h"
#include "solo_types.h"
// 1. Change the license if necessary
char __license[] SEC("license") = "Dual MIT/GPL";
struct event_t {
// 2. Add ringbuf struct data here.
} __attribute__((packed));
// This is the definition for the global map which both our
// bpf program and user space program can access.
// More info and map types can be found here: https://www.man7.org/linux/man-pages/man2/bpf.2.html
struct {
__uint(max_entries, 1 << 24);
__uint(type, BPF_MAP_TYPE_RINGBUF);
__type(value, struct event_t);
} events SEC(".maps.print");
SEC("kprobe/tcp_v4_connect")
int BPF_KPROBE(tcp_v4_connect, struct sock *sk)
{
// Init event pointer
struct event_t *event;
// Reserve a spot in the ringbuffer for our event
event = bpf_ringbuf_reserve(&events, sizeof(struct event_t), 0);
if (!event) {
return 0;
}
// 3. set data for our event,
// For example:
// event->pid = bpf_get_current_pid_tgid();
bpf_ringbuf_submit(event, 0);
return 0;
}
Currently, BumbleBee only supports eBPF applications written in C, but support for Rust eBPF applications is already in the plan.
BumbleBee is built on top of libbpf to gain the benefits of BPF CO-RE (compile once, run anywhere). Alternative options for building eBPF programs are BPF Compiler Collection (BCC) or using libbpf directly.
The BumbleBee project is open-source software available under the Apache 2.0 license. The source code is available at GitHub. If you are interested in eBPF development, check it out and make a contribution.