非公式翻訳:eBPF Superpowers (CNDT2022 Keynote)

CloudNative Days Committee
33 min readNov 22, 2022

CloudNative Days Tokyo 2022 Day2が開幕しました。本日のキーノート枠では、Isovalent社のTechnical Community AdvocateであるTracy P Holmes氏から、クラウドネイティブな世界におけるeBPFの強力さについてお話いただきます。

日本語の字幕を用意するのが難しく、Mediumで同氏のセッションの書き起こしと日本語翻訳をご用意しました。セッション視聴のお供に、また後から見返すためにもお使いください!

(なお、本書き起こしと翻訳は非公式なものとなります。正確な内容を保証するものではなく、あくまでセッション視聴の参考とお考えください)

翻訳・編集:Yoshiki Fujiwara @antiberial, Kohei Ota @_inductor_, Hayakawa Yutaro @YutaroHayakawa, Masato Nabeshima @nabemasat

Cloud Native BPF Superpowers with eBPF

Tracy P Holmes

Technical Community Advocate, Isovalent

Hi, my name is Tracy P Holmes. l am a technical community advocate at Isovalent. We’re the company behind the Cilium Networking Project, which you may have come across. It brings the power of eBPF to Kubernetes networking. And I’m here today to talk about eBPF and why you’re most likely going to be using more and more eBPF-based tooling in the near future. So let me start by talking about what it is.

私はIsovalentのテクニカルコミュニティアドボケイトを務めています。皆さんも目にしたことがあるかもしれませんが、私たちはCilium Networking Projectを運営している会社です。これはeBPFのパワーをKubernetesネットワーキングにもたらすプロジェクトです。今日ここに来たのは、eBPFについて、そしてなぜ近い将来「ますます多くのeBPFベースのツールを使うことになるのか」についてお話しするためです。それでは、まずeBPFとは何かということからお話ししましょう。

What is eBPF?

Convention and tradition dictates we must spell out an acronym. So in this case, eBPF stands for extended Berkeley Packet Filter. And while we could go into the history of why it’s called that, it’s honestly not important, nor very important for what we’re talking about today. However, it is helpful and more important to know what eBPF does. And what is that?

私たちは慣習と伝統によって、略語の使用を強いられています。ここでは、eBPFとはextended Berkeley Packet Filterを略したものです。なぜそう呼ばれているのか歴史を紐解いていくこともできますが、正直なところ、今日話す内容にとってはそんなに重要ではありません。eBPF の機能を理解することこそが、有益でより重要なことなのです。それではeBPFとは何でしょうか?

Well, eBPF makes the kernel programmable. You can write programs and have them run in the kernel without having to write a kernel module. And you can load those programs into the kernel dynamically as you need them. Now, as some of you may or may not know, we typically write application code in userspaces.

eBPFによってカーネルをプログラマブルに扱えるようになります。つまりカーネルモジュールを作成しなくても、独自のプログラムを書いてカーネルで実行できます。これらのプログラムは、必要に応じて動的にカーネルに読み込むことができます。ご存知かは分かりませんが、通常アプリケーションコードはユーザー空間に記述されます。

Run custom code in the kernel

eBPF enabled apps have a userspace part that can load eBPF programs into the kernel.

Each program is triggered by some kind of event. It can be that a network packet arrives or that an application calls a syscall or the kernel hits a particular trace point. Whenever that event is hit, if there’s an eBPF program associated with that event, it gets run.

eBPFに対応したアプリは、ユーザー空間に存在しながら、eBPFプログラムをカーネルにロードすることができます。各プログラムは、何らかのイベントが引き金となり起動します。ネットワークパケットが到着したり、アプリケーションがシステムコールを呼び出したり、あるいはカーネルが特定のトレースポイントに到達した場合などがそれに当たります。こうしたイベントが発火するたびに、関連付けられたeBPFプログラムが実行されます。

Dynamically change kernel behavior

Let’s talk about dynamically changing kernel behavior. So we can load custom programs into the kernel and attach them to events so that the program gets run whenever that event occurs. And you will hear me say that more than once, so just warning you in advance.

カーネル動作の動的変更についてご紹介しましょう。つまりカスタムプログラムをカーネルに読み込み、それらをイベントにアタッチして、そのイベントが発生するたびにプログラムを実行することができます。これから、このような「イベントが発生するたびにプログラムが実行される」話を何度もすることになりますので、前もってお伝えしておきます。

So here we have an application developer that wants to make a kernel change of some type. So here’s what you need to know. Kernel changes can be really hard to do. They can take a long time or both. First of all, the community has to agree on even wanting to make the change. Then you have to write the code, which can definitely be difficult to do. And even when it does reach the upstream kernel, it may be years before you see it in your favorite Linux distributions.

ここに、カーネルにある種の変更を加えたいと思っているアプリケーション開発者がいます。覚えておいて欲しいのですが、カーネルに変更を加えることは非常に難しい場合があります。そして長い時間がかかることもあります。あるいはその両方ということもありえます。まず第一に、コミュニティは変更内容に同意する必要があります。次に、コードを書く必要がありますが、これも非常に困難な作業かもしれません。そして、その変更が上流のカーネルに辿り着いたとしても、お気に入りのLinuxディストリビューションで使えるようになるまでには何年もかかるかもしれません.

Think about some of the kernel releases that you all are working with just as a thought. However, this is one of the reasons you’re hearing more about eBPF. Most distributions support it, and with it you can make kernel modifications instantly. Write in an eBFP program, load it, and now we dynamically change the machine behavior without even having to reboot the machine. I am going to say that again because I think this is one of the most amazing things. Write an eBPF program, load it. And now we’ve dynamically changed the machine behavior. And you didn’t even have to reboot the machine.

This is especially useful if you want to mitigate a kernel vulnerability.

みなさんが作業しているカーネルリリースのいくつかを思い起こしてください。とはいえ、これがeBPFについて耳にすることが増えた理由の一つです。ほとんどのディストリビューションがeBPFをサポートしており、これを使えばカーネルを即座に変更することができます。eBPFプログラムを作成して読み込むと、マシンを再起動する必要さえなく、マシンの動作を動的に変更できます。これがeBPFの最も素晴らしい特徴の1つだと思うので、繰り返しお伝えします。eBPFプログラムを作成し、読み込むと、マシンを再起動する必要さえなく、マシンの動作を動的に変更できます。これは、カーネルの脆弱性を緩和したい場合に特に役立ちます。

eBPF code has to be safe

All right. So it’s important to know that the eBPF Code has to be safe. eBPF programs run in the kernel, so they have to be safe to run. They must not crash, and they must not loop definitely. To ensure this, there are some rules about what you can and can’t do in an eBPF program, and there’s a verification step that checks that the eBPF Code meets those requirements.

For example, an eBPF program must check that a pointer is non null before it tries to dereference it. If you don’t check that the pointer is non null your eBPF code will be rejected. For security reasons, there are also rules about what memory a given eBPF program is allowed to access. Because of these rules, people sometimes describe eBPF Programs as being sandboxed, and that is true. But for those of us in the container world, it’s also a bit confusing and potentially misleading. It’s not the same as this. It’s not the same kind of sandboxing as containers. eBPF is not a replacement for containers. So let’s have a look at what it means to be able to run eBPF programs in a Kubernetes environment.

そして、重要なことなので覚えておいてほしいのですが、eBPFコードは安全でなければなりません。eBPFプログラムはカーネルで実行されるため、安全に実行できる必要があります。クラッシュしてはならず、絶対にループしてはなりません。これを確実なものとするために、eBPFプログラムができること/できないことについて、いくつかルールがあります。またeBPFコードがそれらの要件を満たしていることを確認するための、検証ステップが存在します。たとえばeBPFプログラムは、ポインタを逆参照する前に、ポインタがnullでないことを確認する必要があります。ポインタがnullでないことを確認できなければ、eBPFコードのアクセスは拒否されます。セキュリティ上の理由から、特定のeBPFプログラムがアクセスできるメモリについてもルールがあります。これらのルールのせいで、eBPFプログラムはサンドボックス化されていると説明する人もいます。これは事実ですが、コンテナの世界にいる私たちにとっては、少し混乱や誤解を招く可能性もあります。eBPFはコンテナと同じではありません。eBPFはコンテナと同じ種類のサンドボックスではありません。eBPFはコンテナに代わるものではありません。それでは、Kubernetes環境でeBPFプログラムを実行できることが何を意味するか探ってみましょう。

Programmable kernel in Kubernetes

So we can load custom programs into the kernel and attach them to events. So that the program gets run whenever that event occurs. Most of what I’m about to say is applicable to environments running multiple applications, but as an example, let’s turn to what that means in a Kubernetes environment.

さきほどお伝えしたように、カスタムプログラムをカーネルに読み込んで、イベントにアタッチできます。その結果、イベントが発生するたびにプログラムが実行されます。これから説明することの大半は、複数のアプリケーションを実行する環境に当てはまりますが、例として、それがKubernetes環境で何を意味するのかに目を向けてみましょう。

One kernel per host

In Kubernetes, our applications are running as containers inside pods, but there is only one kernel per host. Every container shares the same kernel. There’s one kernel on a virtual machine, and it’s shared by all of the processes and all containers.

Whenever an application wants to do pretty much anything like read or write to a file or make a network request, it can’t talk directly to hardware. So it has to ask the kernel to do that on its behalf. There’s one kernel and it’s handling work like this for all applications. In fact, there’s not a lot that userspace applications can do without the assistance of the kernel.

Maybe do a little bit of basic math, but the kernel is going to get involved whenever anything interesting happens. If you want to create a new container, guess what? That also needs help from the kernel.

Kubernetesでは、アプリケーションはPod内のコンテナとして実行されますが、ホストごとに1つのカーネルしかありません。すべてのコンテナは同じカーネルを共有します。仮想マシンには1つのカーネルがあり、すべてのプロセスとコンテナで共有されます。アプリケーションの動作の大半、例えばファイルの読み取りや書き込み、またはネットワーク要求の作成などでは、ハードウェアと直接対話することはできません。その代わりに、カーネルにハードウェアと対話を行うように依頼する必要があります。このような作業をすべてのアプリケーションに対して行っているのは、ただ1つのカーネルです。実際、ユーザー空間のアプリケーションが、カーネルの支援なしにできることは多くありません。初歩的な算数ですが、何か興味深いことをするときには大抵カーネルが関与しています。新しいコンテナを作成したい場合はどうでしょう?もちろん、これにもカーネルの助けが必要です。

Kernel aware of everything on the host

So the kernel is aware of everything that’s happening and all of the processes and all the containers on the host. And it has access to information about all of these processes stored in kernel data structures.

したがってカーネルは、ホスト上で起こっている全てのこと、全てのプロセス、全てのコンテナを把握しています。またカーネルのデータ構造に格納されている、これらすべてのプロセスに関する情報にアクセスできます。

eBFP programs can be aware of everything

So if we attach eBPF programs to the right events in the kernel, they can be aware of all of the interesting things that are happening too. And we can write userspace code to communicate with these programs and bring this information together in ways that are really useful for observability and security. We can even redirect or drop network packets from inside eBFP, and that’s the basis of Cilium networking.

つまり、eBPFプログラムをカーネル内の適切なイベントにアタッチすると、あらゆる興味深い事象の発生を認識できます。また、これらのプログラムと通信するためのユーザー空間コードを記述し、これらの情報を集約することで可観測性やセキュリティの実現に役立てることができます。eBFP内からネットワークパケットをリダイレクトまたはドロップすることもできます。これがCiliumネットワーキングの基礎です。

eBPF apps have a view across the entire node

eBPF apps have a view across the entire node enabling deep observability. So what we’re going to do next, is you’re going to see a couple of examples of observability tools being built around eBPF.

eBPFアプリにはノード全体を見渡すビューがあり、高い可観測性を実現します。次にeBPFをベースに構築された可観測性ツールの例をいくつか見てみましょう。

Cilium Hubble observability

Now this is network observability using a component of Cilium called Hubble. I like to make an inside joke with myself that they need to update Hubble to the new telescope name. Anyway, Cilium is connecting components together or networking, and Hubble allows us to observe networking, network packets as they flow through that network. We can see individual packets. We can generate events that go to Prometheus, then travel to Grafana, and that allows us to see things like latency or the number of packets that get dropped or any number of wonderful bits of data. And we can collect it very efficiently because we use eBPF to do it.

これはHubbleと呼ばれるCiliumのコンポーネントを使用したネットワーク可観測性ツールです。『「ハッブル」を新しい望遠鏡の名前(※訳註 ジェイムズ・ウェッブ宇宙望遠鏡)に変える必要があるんじゃない?』と、内輪でジョークを言うのが好きです。それはさておき、Ciliumはコンポーネントを相互に接続すること、つまりネットワーキングを行っており、Hubbleを使用すると、ネットワーキングやネットワークパケットがそのネットワークを流れる様子を観察できます。個々のパケットを調べることもできます。Prometheusに送信するイベントを生成できるので、Grafanaを見れば、遅延やドロップされたパケットの数、その他のあらゆるデータを確認できます。Prometheus に移動してから Grafana に移動するイベントを生成できます。その結果、遅延やドロップされたパケットの数、その他のあらゆるデータを確認できます。またeBPFを使用しているため、とても効率的にデータを収集できます。

PIXIE flame graph

Another example is Pixie. It’s also a CNCF project and they have a ton of different tools and ways of measuring all kinds of metrics across clusters. This is a flame graph and many of us have seen one showing how the CPU is being used. The difference, however, this particular frame graph is collecting CPU usage across an entire cluster and then aggregating in it. And I think that is really, really cool.

その他の例としてPixieがあります。こちらもCNCFプロジェクトであり、クラスタ全体であらゆる種類のメトリックを測定する、さまざまなツールと方法を多数提供しています。これはフレームグラフです。多くの人が、単一ノードのCPUの使用状況を示すグラフを見たことがあるでしょう。しかしこのフレームグラフは、クラスタ全体のCPU使用率を収集し、表示しています。これは本当に素晴らしいことだと思います。

eBPF tools have a view across the entire node enabling network efficiency

The project that I mentioned earlier, Cilium uses eBPF to create a more efficient network.

All right, so this pretty full diagram shows how container networking traditionally works in Kubernetes. We use namespaces to isolate our pods one from another. Typically, a pod is created with its own network namespace, which means it has its own TCP/IP stack and it’s connected to the host network using a virtual ethernet pair.This means the kernel is running a networking stack for every pod, so whenever a packet arrives or leaves a pod, it has to traverse two network stacks on the same machine: ones on the host, the other is inside the pod and the two are isolated from each other. With an eBPF-based networking solution, we can be much more efficient. We can replace a lot of the host networking stack with a more straightforward implementation and eBPF.

先ほど私が言及したプロジェクトであるCiliumは、eBPFを使用してより効率的なネットワークを作成します。この非常に複雑なダイアグラムは、コンテナネットワーキングがKubernetesでこれまでどのように実装されてきたかを示しています。PodとPodの分離には、名前空間が使用されます。通常、Podは独自のネットワーク名前空間で作成されます。つまり独自のTCP/IPスタックがあり、仮想イーサネットのペアを使用してホストネットワークに接続されます。これは、カーネルがすべてのPodに対してネットワークスタックを実行していることを意味します。つまり、パケットは送信・受信に関わらず、同じマシン上で2つのネットワークスタックを通過しなければなりません。1つはホスト側のもの、もう1つはPod側のものです。両者は互いに隔離されています。eBPFベースのネットワーキングソリューションを使用すると、はるかに効率的な実装が可能です。多くのホストネットワークスタックを、より単純な実装とeBPFに置き換えることができます。

First of all, we can hook eBPF Code into events that are triggered as close as possible. So when a packet arrives at the physical network card, this is called XDP or Express Data Path, we can see the destination IP address and map that straight to the endpoint that happens to be in the pod. And we can send the packet straight to the pod’s virtual ethernet interface where it can be handled by the pod’s network stack.

まず、eBPFコードを物理ネットワークカードに非常に近い場所でトリガーされるイベントにフックできます。これはXDP(eXpress Data Path)と呼ばれており、そこから宛先IPアドレスを直接Podに紐づけることができます。そして、パケットを(※訳註 ホスト側ではなく)Pod側の仮想インターフェースに直接送信して、Pod側のネットワークスタックに処理させることができます。

Cilium eBPF (receive path)

Here’s another flame graph. We can even take a look at this in this particular flame graph. Here we can see what’s happening when a packet arrives. It spends a bit of time being handled by eBPF Code and then it arrives in the pods TCP/ IP stack and from there into the socket code where it eventually gets read by the receiving application.

こちらは別のフレームグラフです。このフレームグラフを見ることによって、パケットを受信したときに何が起こっているのか確認できます。パケットはeBPFコードによって短時間で処理され、PodのTCP/IPスタックに到着します。そこからソケットコードに到達し、最終的に受信側のアプリケーションに読み込まれます。

TCP RR (higher is better)

This efficiency makes eBPF-based networking significantly faster than solutions based on IP tables. Not terribly long ago we performed, we, Isovalent. Hi! A whole bunch of benchmarking tests. You can find all the results in analysis on the Cilium blog, but the main takeaway is this: With eBPF, we can do container networking almost as fast as host to host networking. On the screen is a graph of round trip requests response throughput.The blue bar is host to host networking so the sender and receiver are running directly on a host machine. The other bars are all container networking. The red and orange are Cilim and Calico in eBPF mode. The yellow and green have eBPF turned off, so the packets are going through the host and container networking stacks. So you can really see how much faster eBPF is.

All of the above numbers that you see on the screen, including more recent updated numbers, have been published in the CNI Performance Benchmarks section of the Cilium documentation, and it’s continually updated. So when you go to the site to see this particular benchmark, you will see that it’s filed in the latest.

このような効率性により、eBPFベースのネットワーキングは、IPテーブルに基づくソリューションよりも大幅に高速になります。少し前に、私たちIsovalentは大量のベンチマークテストを実施しました。完全な結果はCiliumブログの分析レポートで確認できますが、主要な結論は「eBPFを使用することで、ホスト間ネットワークとほぼ同じ速度でコンテナネットワークを実行できる」ということです。今お見せしているのは、往復リクエスト応答スループットのグラフです。青色のバーはホスト間のネットワークで、送信側と受信側はホストマシン上で直接実行されています。他のバーはすべてコンテナネットワークです。赤色とオレンジ色のバーは eBPFモードのCilimとCalicoです。黄色と緑色のバーではeBPFがオフになっているため、パケットはホストとコンテナのネットワークスタックを通過しています。これらの結果を通して、eBPFがどれほど高速であるかお分かり頂けるでしょう。

スライド上の数値はすべて、最近更新されたものを含め、CiliumドキュメントのCNIパフォーマンスベンチマークセクションで公開されており、継続的に更新されています。したがって、サイトにアクセスすれば、このベンチマークの最新の結果を見ることができます。

eBPF tools have a view across the entire node without any app or config changes

eBPF tools have a view across the entire node.The good thing about this is you don’t have to change anything about your applications. You don’t have to reconfigure anything.

eBPFツールには、ノード全体を横断したビューがあります。そのメリットは、アプリケーションについて「何も」変更する必要がないことです。「何も」再設定する必要はありません。

A sidecar has a view across one pod. Sidecars need yaml. But what if yaml is misconfigured? By using eBPF, you don’t need any app changes. eBPF can see all activity on the node.

サイドカーには、1つのPodに対するビューしかありません。またサイドカーにはyamlが必要です。しかしyamlが正しく設定されていない場合はどうなるでしょうか。eBPFを使用すれば、アプリの変更は必要ありません。eBPFは、ノード上のすべてのアクティビティを確認できます。

eBPF enables powerful Cloud Native tools

And lastly, eBPF enables powerful cloud native tools.

There are quite a few tools and open source projects available today that are leveraging the power of eBPF to get networking, observability and security information in Kubernetes. I’d like to mention a few. So one is Falco, which is a CNCF project that can alert you when a malicious or suspicious event occurs.

Tracee from Aqua Security, which is similar to Falco, but with a lighter weight approach, it lets you define security events in O/P/A or OPA. I also like this particular one because my name is Tracy.

Cilium, which we mentioned earlier is a Kubernetes networking plugin kind of on steroids. New Relic’s Pixie, which was also mentioned earlier, remember that flame graph? It not too long ago got open sourced and applied to join the CNCF as an observability tool.

最後になりますが、eBPFによって強力なクラウドネイティブツールを実現することができます。

現在、多くの利用可能なツールやオープンソースプロジェクトが、eBPFの機能を利用して、Kubernetes上でネットワーキングや可観測性を実現したり、セキュリティ情報を取得したりしています。いくつかの例をご紹介しましょう。

まずはFalcoです。これは、悪意のあるイベントや疑わしいイベントが発生したときにアラートを出すことができるCNCFプロジェクトです。

Aqua SecurityのTraceeはFalcoに似ていますが、より軽量なアプローチで、セキュリティイベントをOPAで定義できます。私の名前が(※訳註 同じ読み方の)Tracyであることも、お気に入りの理由です。

先ほど触れたCiliumは、強化されたKubernetesネットワーキングプラグインです。

同じく先ほどご紹介したNew RelicのPixieですが、あのフレームグラフを覚えていますか?少し前にオープンソース化され、可観測性ツールとしてCNCFへの参加申請が行われました。

Thank you

Anyway, I hope that’s giving you an overview of why eBPF is so powerful and how it’s enabling the creation of some really powerful tools. That said, if you want to learn more about eBPF, there’s a community website at ebpf.io that has tons of information. And if you’d like to learn more about the Cilium project, please come and see us at cilium.io or on our Slack channel at slack.cilium.io. Thanks.

何はともあれ、このセッションを通してeBPFが非常に強力な理由と、eBPFが非常に強力なツールの開発を可能にする方法について、概要を理解いただけたことを願っています。eBPFについて詳しく知りたい方は、コミュニティWebサイトであるebpf.ioにたくさんの情報があります。Ciliumプロジェクトについて詳しく知りたい場合は、cilium.ioまたはSlackチャンネルslack.cilium.ioで私たちに会いに来てください。ありがとうございました。

--

--