「eBPF」がクラウドネイティブを超強力にする。eBPFとは何か? 何ができて、どんな利点があるのか? Cloud Native Days Tokyo 2022基調講演から
2022年11月21日と22日の2日間、クラウドネイティブにフォーカスしたイベント「Cloud Native Days Tokyo 2022」が都内およびオンラインのハイブリッドで行われました。
22日の基調講演に登場したのは、Cilium、Hubble、TetragonなどeBPFを中心としたオープンソースを開発しているIsovalentのTracy P Holmes氏。
Homes氏は、いまクラウドネイティブ関連のテクノロジーとして最も注目されていると言ってよい「eBPF」を紹介するセッション「Cloud Native Superpowers with eBPF」を行いました。
eBPFとはどのようなテクノロジーなのか、それによって何が実現され、どのような利点があるのかが詳しく紹介されています。
本記事ではそのセッションの様子をダイジェストで紹介します。また記事化にあたり、有志による基調講演の非公式翻訳も参照させていただきました。
Cloud Native Superpowers with eBPF
Isovalentでテクニカルコミュニティアドボケイトを務めているTracy P Holmesです。
ご存じかもしれませんが、私たちIsovalentは、CNCF(Cloud Native Computing Foundation)のCilium Networking Projectを支援しています。
これはeBPFのパワーをKubernetesネットワーキングにもたらすプロジェクトであり、ここではeBPFについて、そしてなぜ近い将来「ますます多くのeBPFベースのツールを使うことになるのか」についてご紹介していきます。
eBPFとは何か?
まずeBPFとは何かということからお話ししましょう。eBPFとはextended Berkeley Packet Filterの略です。
eBPFでは何ができるのでしょうか?
eBPFは、カーネルをプログラマブルにするものです。
つまりカーネルモジュールを新たに開発することなく、独自のプログラムを書いて、それをカーネルで実行できます。
eBPFに対応したアプリケーションは、ユーザー空間にありながら、必要に応じてそのプログラムを動的にカーネルにロードできます。
ロードされたプログラムは、ネットワークパケットが到着したり、アプリケーションがシステムコールを呼び出したり、あるいはカーネルが特定のトレースポイントに到達した場合など、何らかのイベントを引き金として起動されるのです。
eBPFならカーネルを動的に変更可能
そもそも、カーネルに変更を加えることは非常に難しく、長い時間がかかるものでした。
カーネルに変更を加えようとした場合、まずはコミュニティとしてその変更内容に同意し、次にカーネルのコードを書きます。カーネルのコードを書くのは、非常に困難な場合もあるでしょう。
その変更がカーネルに実装され、何らかのLinuxディストリビューションで使えるようになるまでには何年もかかるかもしれません。
しかし現在ではほとんどのLinuxディストリビューションがeBPFをサポートしており、eBPFを使うことでカーネルの動作を即座に変更できます。
eBPFプログラムを作成して読み込めば、マシンを再起動する必要さえなく、カーネルの動作を動的に変更できるのです。
これがeBPFの最も素晴らしい特徴の1つですので、あえて繰り返してお伝えしましょう。eBPFプログラムを作成し、読み込むと、マシンを再起動する必要さえなく、カーネルの動作を動的に変更できるのです。
eBPFのプログラムは確実な安全性が必要
ただし、eBPFでカーネルにロードされるプログラムはカーネルで実行されるため、確実に安全である必要があります。
決してクラッシュしてはならず、無限ループも許されません。これらを確実なものとするために、eBPFのプログラムができることとできないことについては、いくつかのルールがあります。
そしてプログラムがそれらの要件を満たしていることを確認するための検証ステップも存在します。
例えば、eBPFのプログラムはポインタを逆参照する前に、ポインタがnullでないことを確認する必要があります。ポインタがnullでないことを確認できなければ、そのプログラムは却下されます。
セキュリティ上の理由から、特定のeBPFのプログラムがアクセスできるメモリについてもルールがあります。
これらのルールのせいで、eBPFプログラムはサンドボックス化されていると説明する人もいます。
これは事実ですが、コンテナの世界にいる方々にとって少し混乱や誤解を招く可能性もあるので説明を付け加えると、eBPFはコンテナと同じ種類のサンドボックスではなく、eBPFはコンテナと同じではありません。eBPFはコンテナに代わるものではない、ということです。
KubernetesにおけるeBPF
続いて、Kubernetes環境でeBPFプログラムを実行することが何を意味するのか、探ってみましょう。
先ほどお伝えしたように、eBPFでは独自のプログラムをカーネルにロードし、イベントにアタッチできます。その結果、イベントが発生するたびにeBPFのプログラムが実行されます。
Kubernetesでは、アプリケーションはPod内のコンテナとして実行されますが、ホストごとに1つのカーネルが実行されるため、ホスト上のすべてのコンテナは同じカーネルを共有します。
仮想マシンでもカーネルが1つ実行され、そのカーネルがすべてのプロセスとコンテナで共有されます。
アプリケーションの動作のほとんど、例えばファイルの読み取りや書き込み、ネットワークへのリクエストなどの処理は、カーネルによって処理されます。
事実上、ユーザー空間のアプリケーションがカーネルの支援なしにできる処理はごく少数です。
したがってカーネルは、ホスト上で起こっている全てのこと、全てのプロセス、全てのコンテナを把握しています。またカーネルのデータ構造に格納されている、これらすべてのプロセスに関する情報にも当然ながらアクセスできます。
ということは、eBPFプログラムをカーネル内の適切なイベントにアタッチすることで、Kubernetesのノードにおけるあらゆる事象の発生を認識できる、ということなのです。
また、eBPFのプログラムと通信するためのアプリケーションをユーザー空間で実行し情報を集約することで、Kubernetesにおける可観測性やセキュリティの実現に役立てることができます。
さらに、eBFPのプログラム内でネットワークパケットをリダイレクトまたはドロップする、といった処理もできます。これはCiliumネットワーキングの基本的な仕組みになっています。
eBPFによる可観測性ツール
では、eBPFをベースに構築された可観測性ツールの例をいくつか見てみましょう。
これは「Hubble」と呼ばれる、Ciliumのコンポーネントを使用したネットワーク可観測性ツールです。
Hubbleを使用すると、ネットワーキングやネットワークパケットが流れる様子を観察できます。個々のパケットを調べることもできます。
Prometheusに送信するイベントを生成できるので、Grafanaを見れば、遅延やドロップされたパケットの数、その他のあらゆるデータを確認できます。eBPFを使用することで、とても効率的にデータを収集できるのです。
PixieもCNCFプロジェクトです。これは、クラスタ全体のあらゆる種類のメトリックを測定する、さまざまなツールと方法を多数提供しています。いま表示しているのはフレームグラフです。
多くの方は単一ノードのCPUの使用状況を示すグラフを見たことがあると思いますが、このフレームグラフはクラスタ全体のCPU使用率を収集し、表示しています。これは本当にクールな機能ですよね。
eBPFを用いて効率的なネットワークを実現
先ほど私が言及した、CiliumがeBPFを使用してより効率的なネットワークを作成する点について紹介しましょう。
この非常に複雑なダイアグラムは、従来、Kubernetesでコンテナネットワーキングが実装される方法を示しています。
PodとPodの分離には名前空間が使用されるため、通常は独自のネットワーク名前空間においてPodが作成されます。
そして名前空間ごとにそれぞれのTCP/IPスタックが用意され、その仮想イーサネットのペアがホストネットワークの接続に利用されます。
これは、カーネルがすべてのPodに対してネットワークスタックを実行していることを意味します。
つまり、パケットは送信、受信に関わらず、同じマシン上で2つのネットワークスタックを通過しなければなりません。1つはホスト側のもの、もう1つはPod側のものです。
これが、eBPFベースのネットワーキングソリューションを使用することで、はるかに効率的な実装が可能になります。多くのホストネットワークスタックを、より単純な実装とeBPFに置き換えることができるのです。
まず、eBPFコードを物理ネットワークカードに非常に近い場所でトリガーされるイベントにフックできます。これはXDP(eXpress Data Path)と呼ばれており、そこから宛先IPアドレスを直接Podに紐づけることができます。
そして、パケットをPod側の仮想インターフェースに直接送信して、Pod側のネットワークスタックに処理させることができます。
こちらは別のフレームグラフです。このフレームグラフを見ることによって、パケットを受信したときに何が起こっているのか確認できます。
パケットはeBPFのプログラムによって短時間で処理され、PodのTCP/IPスタックに到着します。そこからソケットコードに到達し、最終的に受信側のアプリケーションに読み込まれます。
このような効率性により、eBPFベースのネットワーキングは、IPテーブルに基づくソリューションよりも大幅に高速になります。
eBPFは高速なネットワークを実現可能
少し前に、私たちIsovalentは大量のベンチマークテストを実施しました。完全な結果はCiliumブログの分析レポートで確認できますが、主要な結論は「eBPFを使用することで、ホスト間ネットワークとほぼ同じ速度でコンテナネットワークを実行できる」ということです。
今お見せしているのは、往復リクエスト応答スループットのグラフです。
青色のマーカーはホスト間のネットワークで、送信側と受信側はホストマシン上で直接実行されています。他のマーカーはすべてコンテナネットワークです。
赤色とオレンジ色のマーカーは eBPFモードのCiliumとCalicoです。
黄色と緑色のマーカーではeBPFがオフになっているため、パケットはホストとコンテナのネットワークスタックを通過しています。
これらの結果を通して、eBPFがどれほど高速であるかお分かり頂けるでしょう。
スライド上の数値はすべて、最近更新されたものを含め、CiliumドキュメントのCNIパフォーマンスベンチマークセクションで公開されており、継続的に更新されています。サイトにアクセスすれば、このベンチマークの最新の結果を見ることができます。
eBPFは設定不要で全体のビューを持てる
可観測性についての話。
eBPFツールは、ノード全体を横断したビューを持つこともできます。
そのメリットは、アプリケーションについて「何も」変更する必要がないことです。「何も」設定する必要はありません。
従来の方法であるサイドカー方式では、1つのPodに対するビューしか持てません。またサイドカーには設定ファイルのyamlが必要です。
eBPFではアプリの変更も設定も必要なく、ノード上のすべてのアクティビティを確認できます。
eBPFを活用したCNCFのプロジェクトを紹介
現在、多くの利用可能なツールやオープンソースプロジェクトが、eBPFの機能を利用して、Kubernetes上でネットワーキングや可観測性を実現したり、セキュリティ情報を取得したりしています。
最後にいくつかの例をご紹介しましょう。
まずは「Falco」です。これは、悪意のあるイベントや疑わしいイベントが発生したときにアラートを出すことができるCNCFプロジェクトです。
Aqua Securityの「Tracee」はFalcoに似ていますが、より軽量なアプローチで、セキュリティイベントをOPA(Open Policy Agent)で定義できます。私の名前が(同じ発音の)Tracyであることも、お気に入りの理由です。
先ほど触れた「Cilium」は、強化されたKubernetesネットワーキングプラグインです。
同じく先ほどご紹介したNew Relicの「Pixie」ですが、少し前にオープンソース化され、可観測性ツールとしてCNCFへの参加申請が行われました。
おわりに
このセッションを通してeBPFが非常に強力な理由と、eBPFが非常に強力なツールの開発を可能にする方法について、概要を理解いただけたことを願っています。
eBPFについて詳しく知りたい方は、コミュニティWebサイトであるebpf.ioにたくさんの情報があります。Ciliumプロジェクトについて詳しく知りたい場合は、cilium.ioまたはSlackチャンネルslack.cilium.ioで私たちに会いに来てください。
ありがとうございました。
あわせて読みたい
Rust言語を推進する「Rust Foundation」がフルタイムのエンジニアを2名募集中。年収10万ドルから15万ドル
≪前の記事
ローカル環境を汚さない開発環境Devbox/AWS SIer世界一にクラスメソッド/VSCode WebでPythonの実行やデバッグ可能にほか、2022年12月の人気記事