LambdaとFargateがさらに高速化?!MicroVMをわずか5ミリ秒で起動 Firecracker open-source innovation #OPN402 #reinvent

CX事業本部の岩田です。

先日Lambdaの内部アーキテクチャに関するブログを書きましたが、もう少し色々と理解を深めるべくFirecrackerに関するセッションを漁っているところです。今回紹介するセッションではFirecrackerのロードマップ紹介やデモが含まれており、Firackracerのスナップショット取得&復元技術を使うことでMicroVMがわずか5ミリ秒で起動するという衝撃的なデモを見ることができます。このスナップショット技術がFargateやLambdaの基盤に適用されれば、FargateのタスクやLambda実行環境のさらなる高速起動が期待できそうです。とても楽しみですね。

それでは早速セッション内容を紹介していきます。

資料

セッション動画

スライド

Firecracker open-source innovation

※以後の画像はすべて上記スライドからの引用になります。

Firecrackerの概要について

AWSでは過去6年間に渡ってNitroプラットフォームに投資を続けてきました。EC2を高速化し、顧客に提供する際のコストを下げるためです。AWSは同様にサーバーレスのプラットフォームにも投資を行っており、そのうちの1つがFirecrackerです。Firecrackerについて簡単に説明すると、軽量の仮想化技術であり、顧客のワークロードを保護するための柔軟かつ安全なバリアであると言えます。

Firecrackerは2017年に開発をスタートし、2018年からAWSの本番環境で利用されています。現在LamdbaというサービスはFirecracker上で数十万の顧客のワークロードを稼働させており、Lambda Functionの呼び出しは毎月数兆回も実行されています。

Firecrackerで解決したい課題

このグラフを例にFirecrackerによって解決したい課題について考えてみます。縦軸がサーバーのリソース(CPU,メモリ)、横軸は時間です。ある顧客の1つのLambda Functionについて考えたとき、ワークロードは時間によって上下するのが一般的です。よって、同一Lambda Functionの多数のコピーを同一ハードウェア上で稼働させると、時間帯次第でサーバーのリソースを全て使い切ったり、あるいは全くサーバーのリソースを消費しなかったり、という状況が発生します。このリソースを消費しない状況というのはサービスプロバイダー(AWS)側からすると非効率的です。

ハードウェアの割当を効率化するには、異なる特徴をもつ複数のLambda Functionを同一ハードウェア上に割り当てることが重要です。このグラフの例では、黄色のワークロードがリソースを消費している時間帯は赤色や青色のワークロードはあまりリソースを消費していません。逆に赤色や青色のワークロードが多くのリソースを消費している時間帯には黄色のワークロードはリソースをあまり消費していません。このような理想的なシステムを構築するには、システム負荷に合わせて柔軟にスケール可能なセキュリティ境界が必要です。これを実現しているのがFirecrackerです。

Firecrackerがもたらすメリット

Firecrackerをサーバーレスアーキテクチャの基盤に利用することで、大きく3つのメリットを得ることができます。

  1. まず1つ目はセキュアな環境分離です。FirecrackerはVMM(Virtual Machine Monitor)であり、仮想化技術によってワークロード間の環境を分離します。また、MicroVMから利用できる仮想デバイスは必要最低限のモデルに制限されています。
  2. 次に2つ目は速度です。Lambda FunctionやFargateのコンテナを利用したマイクロサービスでは数千のLambda Functionやコンテナを高速に起動することが可能です。FirecrackerのMicroVMはホストOS上のプロセスであり、わずか4ミリ秒程度で起動し、ゲストのLinuxOSは約125ミリ秒で起動します。
  3. 最後に3つ目は効率的にスケールすることです。FirecrackerのMicroVMには必要最低限な機能のみ実装されており、仮想化によるメモリのオーバーヘッドはわずか5MB程度です。そのため、データセンターに設置されたホスト上に数千のMicroVMを稼働させることが可能です。

Firecrackerのアーキテクチャについて

Firecrackerはこのようなアーキテクチャになっています。

Firecrackerのアーキテクチャ

画像の左側では様々な形状のMicroVMが動作しています。これは全てのMicroVMで別々のメモリ,CPUの組み合わせが利用できることを表しています。そしてこれらは全て実際の物理的なリソースを利用します。

画像の右側は個々のMicroVMの詳細を表しています。上部にはゲストOSがあり、コンテナやLambda Functionのワークロードを実行することが可能です。ゲストOSより下のレイヤにはMicroVMを制御するためのREST APIのセットに加えて、必要最小限のネットワーク、ストレージとメタデータサービスが含まれます。

FirecrackerのOSS化について

AWSはLambdaとFargateのためにFirecrackerの開発をスタートしましたが、FirecrackerはOSSのコミュニティにとっても有用な技術であることに気付きました。FirecrackerはクリーンなAPIを持ち、AWS以外の環境上でも動作させることが可能です。同時にFirecrackerをOSS化することで、AWSの顧客に対してLambdaがどのような環境下で実行されているか公開できることに気付きました。こうしてFirecrackerはre:invent2018からApache 2.0ライセンスに基づいてOSS化されました。

FirecrackerをOSS化した結果、2019/11/22時点で48のOSSコミュニティから110のコントリビューションがありました。これは全コミットの18%に相当します。さらに数十のコミュニティからバグポート、追加機能のリクエスト、RFCへのフィードバックを得ることができました。

さらにOSS化したことによって

等のプロダクトがFirecrackerを利用するようになりました。

Weave Works Ignite/Firekubeについて

ここからスピーカーが交代し、Firecrackerを利用したWeave Works社のプロダクトIgniteとFirekubeについての解説&デモに入ります。セッション動画の10:00~17:00あたりをご覧下さい。概要は以下の通りです。

  • IgniteはFirecrackerを使用してVMのようにコンテナーを起動する
  • IgniteはYAMLファイルから設定をロードしてMicroVMを起動する
  • MicroVMはホストOSと別のカーネルを実行できる
  • FirekubeはIgniteとFirecracker上で動作するKubernetesのクラスター

Firecrackerのロードマップについて

ここから再度スピーカーが交代し、Firecrackerのロードマップについての解説となります。

FirecrackerのロードマップはAWSの顧客、OSSコミュニティ両方の意見を反映して作成されています。2019年の夏にGitHubのリポジトリ上で多数のissueを起票し、多くの人達から意見を収集しました。そしてその後18ヶ月間のロードマップを作成しています。もしロードマップを確認したければ、GitHubリポジトリのProjectsから確認することが可能です。

2019年を振り返るとFirecrackerは以下のような改善に取り組んできました。

今後の取り組みですが、基本的には前述のFirecrackerがもたらす3つのメリットについて引き続き注力し、サーバーレスコンピューティングのプラットフォームとして求められるコア機能を改善していきます。特に速度面に関してはMicroVMのスナップショット取得/復元機能に取り組みます。

Firecrackerのスナップショット機能について

ここから再度スピーカーが交代し、Firecrackerのスナップショット機能についての話になります。

なぜスナップショット機能を実装するのか

Firecrackerはサーバーレス/コンテナ環境を実現するための基盤です。サーバーレス/コンテナ環境を改善するために必要な次のステップとして、不要になったMicroVMを保存しておき、必要になった時に復元する機能が必要になると考えました。AWSが機能改善に取り組む際、その90%は顧客からのリクエストに基づいています。残りの10%に関しては、顧客からの明確なリクエストではありませんが、顧客とのやりとりやフィードバックから得られた考察に基づいています。スナップショット機能に関してはこの両方が該当し、実際にGitHub上でOSSコミュニティからリクエストを受けています。また、スナップショット機能を実装することはFirecrackerを利用する顧客にとっても良いことだと考えました。

もう1つの理由は速度のさらなる改善です。re:invent2018の時点でMicroVM上でLinuxカーネルが起動するまでに必要な時間は125ミリ秒程度でした。125ミリ秒は十分高速な数値ではありますが、さらなる高速化が実現できないかを考えました。新しくMicroVMを起動する際は、Firecrackerのプロセスを新たに起動し、REST API経由で仮想メモリの量や仮想デバイスの設定を行い、ゲストのLinuxカーネルを起動するという流れになります。最終的にユーザースペースでinitが実行されるまでの所要時間が125ミリ秒です。これらの全てのステップを実効する代わりに、初期化処理が全て完了したMicroVMのスナップショットを取得しておき、スナップショットからMicroVMを起動すると、起動時間は約5ミリ秒となり25倍の改善が実現できます。

なぜFirecrackerのスナップショット機能は早いのか

なぜFirecrackerのスナップショット機能はこんなに早いのでしょうか?Firecrackerのコアは必要な機能のみに最小化されており、保存/復元する対象が少ないためです。保存/復元対象は3つに分類されます。

  1. 1つ目はVMの内部状態です。これはホストOSのKVMとやりとりを行うためのデータ構造で、vCPU上でペンディング状態のイベントや割り込みコントローラーの状態などです。
  2. 2つ目は仮想デバイスの状態です。前述の通りMicroVMのデバイスモデルは最小化されており、PIOデバイスとVirtIO経由でのMMIOをサポートしています。PIOデバイスは必要最小限のキーボード実装とシリアルコンソールで、これらはステートレスであるため、保存/復元する必要がありません。MMIOに関してはVsockをサポートしており、仮想デバイスの状態を保存/復元します。ブロックデバイスの場合はホストOS上でのパスになり、NICはホストOS上のTAPデバイスの名前にマッピングされます。
  3. 3つ目はゲストOSのメモリです。FirecrackerのMicroVMはメモリマップファイルを使用するため、スナップショット取得時にMicroVMのメモリ上の全データを書き出す必要がありません。ダーティーデータのみメモリマップファイルに書き出します。

スナップショット取得の流れ

スナップショットの取得は以下の流れで実施されます。

  • vCPUの停止と状態のシリアライズ
    • まずはvCPUを停止します。そうしないとスナップショット取得中にMicroVMの状態が変更され、スナップショットに矛盾が生じるからです
  • 状態の保存
    • KVMと通信するために使用している内部データ構造を全てシリアライズして保存します
  • 仮想デバイスのシリアライズ
    • MMIOデバイスをシリアライズして保存します。ブロックデバイスであればホストOS上のファイルパス、NICはホストOS上のTAPデバイスの名前にマッピングされます
  • メモリの同期
    • 最後にゲストOSのダーティーページをメモリマップファイルにフラッシュします
  • MicroVMの停止
    • スナップショット取得完了後にMicroVMを停止します

実際のスナップショットの取得の流れです。

FIracrackerのMicroVM作成の流れ

まずFirecrackerのプロセスを起動した後、いくつかのREST APIを使用してメモリやvCPUの割り当て、仮想デバイスの設定を行い、ゲストOSを起動します。

Firacrackerのスナップショット取得の流れ

次にスナップショット取得のREST APIを実行します。前述の流れの通り、vCPUの停止~MicroVMの停止までの一連の処理が実行され、最終的にMicroVMのスナップショットはホストOS上のファイルとして保存されます。

スナップショットからの復元の流れ

スナップショットからMicroVMを復元する際の流れは以下のようになります

  • スナップショットのチェック
    • まず保存されているファイルがFirecrackerのスナップショットとして妥当であるかのチェックを行います
  • メモリの復元
    • 次にメモリマップファイルからゲストOSのメモリを復元します
  • vCPUの再作成
    • 保存されたMicroVMの状態から、必要なvCPUの数量を読み取ってvCPUを再作成します
  • Firecrackerとデバイスの状態を復元
    • 次にFirecrackerとデバイスの状態を復元します
    • PIOデバイスは保存された状態を持たないため再作成されます
    • MMIOデバイスは再作成され、保存された状態が復元されます
  • vCPUの再開
    • こうしてMicroVMの実行準備が整うと、vCPUの実行が再開されます

制御用のREST API以外は何も実行されていない空のMicroVMにスナップショットを復元する流れを見ていきましょう。

Firacrackerのスナップショットリストアの流れ1

まずスナップショットから復元するためのREST APIを実行します。すると前述の通りスナップショットのチェック~vCPUの再開までの処理が順番に実行されます。

Firacrackerのスナップショットリストアの流れ2

最終的にスナップショットに保存された全ての情報がMicroVMに復元され、MicroVMの再実行が開始します。

スナップショット機能のデモ

最後にFirecrackerのスナップショットに関するデモです。セッション動画の32:35あたりからなので、ここは是非セッション動画をご覧下さい。

デモの概要は以下の通りです。

  • 4,000台のMicroVMを6スレッドで起動
    • OSはAlpine Linux
    • MicroVMはルートファイルシステム用の1つのブロックデバイスと1つのネットワークデバイスを持つ
  • 各MicroVMが小さなネットワークのワークロードを実行
    • ホスト上で動作するiperfサーバーと、各MicroVM内で動作するiperfクライアントの間でランダムなトラフィックを実行し、ランダムな時間スリープする
  • ネットワークの状態を可視化
    • ヒートマップで可視化
    • ネットワークのトラフィック量に応じてヒートマップの色が変化
  • 通常のMicroVM起動と、スナップショットからの復元2パターンでワークロードを実行し、比較する

デモの結果を簡単にまとめると以下の通りです。

  • NWトラフィックのヒートマップから、スナップショットの復元機能がMicroVMの状態を正しく復元できていることが分かる
  • 通常の方式でMicroVMを起動するよりも、スナップショットから復元して起動する方式の方がホストOSのメモリ消費量が少ない
    • 通常方式の場合150GBのメモリを消費
    • スナップショットから復元した場合は14.8GBのメモリを消費
    • MicroVM1台あたり4MB程度効率化されている
  • 通常の方式でMicroVMを起動するよりも、スナップショットから復元して起動する方式の方が高速
    • 通常方式の所要時間は最小100ミリ秒、最大191ミリ秒
    • スナップショットから復元した場合の所要時間は最小2ミリ秒、最大38ミリ秒
  • 通常の方式でMicroVMを起動した場合、ホストOS上ではするよりも、スナップショットから復元して起動する方式の方が高速

まとめ

Firecrackerのスナップショット機能について知ることができ、とても有意義なセッションでした。Firecrackerのロードマップを追いかければ、LambdaやFargateが今後どのように改善されるか先読みできそうなので、今後も定期的にFirecrackerの動向をチェックしていきたいと思います。 とりあえずラズパイ4を買って、改めてFirecrackerを試してみようと思います。