サービスメッシュプロバイダのSolo.ioは先頃、BumbleBeeという名称のオープンソースプロジェクトを発表した。目標とするのは、テンプレートとボイラープレートファイルを自動生成することによる、eBPFアプリケーション開発の簡素化である。その手段として、開発作業をサポートする"レール"と、Dockerライクなエクスペリエンスを提供する。
eBPFは、カスタムロジックによるLinuxカーネルの拡張を可能にするテクノロジである。代表的なユースケースのひとつはネットワークの監視や管理だ。サイドカープロキシや、サービスメッシュのデータプレーンでの採用が増えつつある。その一方で、eBPFアプリケーションの開発とデプロイは、大部分の開発者にとって困難な作業である。CやRustといった言語でカーネルプログラムを記述し、特殊なコンパイラを使ってeBPF用にコンパイルした上で、ターゲットマシンのLinuxカーネルにデプロイする必要がある。さらに、カーネル内のeBPFプログラムとユーザ空間内で対話するためのアプリケーションを、それとは別に用意しなければならない。
eBPFのように複雑なテクノロジスタックを扱う場合、新たな開発者の技術習得手段として実績のあるアプローチのひとつが、ボイラプレートコードの大部分を自動化する"レール"(あるいは推奨形式)を提供する方法である。新参の開発者がクリティカルパス上のコードを数行書けば、あとはツールないしフレームワークがアプリケーション全体を生成してくれるのだ。
Solo.io CEOのIdit Levine氏は言う。
"私たちSolo.ioはeBPFを、アプリケーションネットワークを強化する上で非常に重要なテクノロジだと考えています。昨年1年間は、Istioベースの企業向けサービスメッシュ製品のGloo Meshで、eBPFテクノロジを活用するための開発に取り組んできました。eBPFエクステンションの開発中には、数多くの技術的な課題に直面しました — これを機会として、eBPF開発を効率化するBumbleBeeを作り上げたのです。eBPFのメリットを強く信じる私たちにとって、BumbleBeeをコミュニティと共有してeBPFの普及に一役買えることを、とてもうれしく思っています。
BumbleBeeはまさにそれを実現する。BumbleBeeは開発者に対して、C言語によるコアeBPFコードの記述を可能にする。アプリケーションの他の部分は、コードをカーネル内にデプロイするためのツールや、さらにはeBPFプログラムと通信するユーザ空間UIも含めて、自動的に生成されるのだ。BumbleBeeは、eBPFプログラムを作成するSolo.ioの社内開発から発展したものだ。
BumbleBeeでは、使い慣れた開発環境を一貫性を持って提供する手段として、コンテナ化されたビルド環境を活用する。BunbleBeeを使えば、eBPFプログラムを単一のELFファイルに構築した上で、それをeBPFデプロイメントツールや自動生成されたユーザ空間アプリケーションと合わせて、ひとつのOCIコンテナイメージのパッケージ化することができる。開発者はそのコンテナイメージをプルして、イメージ内のeBPFプログラムをカーネルにデプロイし、ユーザ空間アプリケーション経由で操作すればよい。さらにeBPFプログラムは、K8sクラスタ内など、任意のコンテナ化環境で実行することができる。
BubmleBeeは開発者に対して、Dockerライクなエクスペリエンスを提供する。CLIツールを使って単にbee init
、bee build
、bee run
と実行することで、新たなeBPFプログラムの作成、eBPFプログラムをOCIイメージ内にビルド、eBPFプログラムのこのOCIイメージの実行、といった操作が可能になる。例えばinit
ステップならば、どのタイプのeBPFプログラムを開発したいか、など4つの質問に答えるだけで、eBPFプログラムのソースコードが生成されるのだ。例として、コンソールにログを出力するネットワークプローブでは、次のようなCプログラムのソースコードが生成される。
#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;
}
BumbleBeeでサポートされているのは、現時点ではCで記述されたeBPFアプリケーションのみだが、Rust eBPFアプリケーションのサポートがすでに計画中である。
BumbleBeeはlibbpf上に構築されることにより、BPF CO-RE(compile once, run anywhere)のメリットを活用する。eBPFプログラムを開発する他の選択肢としては、BPF Compiler Collection (BCC)やlibbpfを直接使用する方法がある。
BumbleBeeプロジェクトは、Apache 2.0ライセンス下で使用可能なオープンソースソフトウェアである。そのソースコードはGitHubで公開されている。eBPF開発に興味があるならば、内容を確認した上でコントリビューションを検討するとよいだろう。