Lambdaの裏側を知りたい人にオススメ Firecrackerに関する論文「Firecracker: Lightweight Virtualization for Serverless Applications」の紹介

英語ですが、頑張って読みましょう!!
2020.06.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

CX事業本部@大阪の岩田です。

Firecrackerに関する論文「Firecracker: Lightweight Virtualization for Serverless Applications」を読んだので、かいつまんで内容を紹介させて頂きます。

Firecracker: Lightweight Virtualization for Serverless Applications

NSDI '20というイベントでこの論文の内容について発表しているセッションの動画がYoutubeに上がっていたので、興味のある方は是非こちらもご覧ください。

以下論文の概要です。

Abstract

AWSがFirecrackerを開発するに至った経緯などが簡単に説明されています。

サーバーレスなコンピューティング基盤を顧客に提供するためには、1つのハードウェア上で複数の顧客のワークロードを稼働させつつも、セキュリティとパフォーマンスを適切に分離する必要があります。しかし、従来の仮想化技術は

  • セキュリティレベルは高いものの、オーバーヘッドは大きいOS仮想化技術
  • OSレベルの仮想化と比べるとセキュリティレベルが下がるものの、オーバーヘッドが最小限になるコンテナ型の仮想化技術

という2択であり、強力なセキュリティと最小限のオーバーヘッド両方のニーズを満たすことができませんでした。このニーズを満たすために、サーバーレスワークロードに特化したFirecrackerが開発されたのです。

1 Introduction

Firecrackerの概要について簡単に解説されています。

Firecrackerは、KVM(Kernel-based Virtual Machine)と連携して、サーバレスコンピューティングの実行基盤を提供します。提供される最小限のLinuxゲストカーネル構成により、コンテナーあたり5MB未満のメモリオーバーヘッドを提供し、125ms未満でアプリケーションコードを起動し、ホストあたり1秒あたり最大150のMicroVMを作成できます。 Firecrackerは2018年からAWS Lambdaの本番環境で利用されており、毎月数百万のワークロードと数兆のリクエストを処理しています。

Firecrackerはサーバーレスおよびコンテナアプリケーション向けに特化して設計されており、必要最低限の機能しか実装されていません。FirecrackerとQEMUを比較すると、Firecrackerには多くの機能が実装されていません。サポートされるデバイスモデルは最小限で、サーバーレスなワークロードを稼働させるために必要最低限の機能しか実装されていません。例えばUSB、PCI、サウンド、ビデオといったデバイスにFirecrackerは対応していません。

2 Choosing an Isolation Solution

どのようにサーバーレスコンピューティング環境の環境分離を実現すべきか、Firecrackerのアーキテクチャー選定に至るまでの経緯について説明されています。

AWSがLambdaというサービスの提供を開始した際は、Linuxコンテナを使用してFunction間の分離を実現し、OSの仮想化によって AWSアカウント間の分離を実現していました。同じ顧客の複数のFunctionは単一のVM内で実行されますが、異なる顧客のワークロードは常に異なるVMで実行されるというモデルです。しかし、セキュリティと互換性のトレードオフ、VMに効率よくワークロードを集約させることの難しさなどからAWSはこのアプローチには満足できなかったそうです。

AWSはこれらの課題を解決するためにLambdaの環境分離モデルを再設計するためのさまざまな方法を評価して、方針を策定しました。評価軸には以下の項目が挙げられます。

  • Isolation

    複数のLambda Functionを同じハードウェア上で実行しつつも、各Lambda実行環境は特権昇格、情報漏えいを引き起こす脆弱性、隠れチャネル、およびその他のリスクに対して安全である必要があります。

  • Overhead and Density

    オーバーヘッドを最小限に抑えて、1台の物理マシンで何千ものLambda Functionを実行できる必要があります。

  • Performance

    Lambda Functionは、ネイティブで実行する場合と同様に実行される必要があります。 また、パフォーマンスは一貫しており、同じハードウェア上で動作する他のLambda Functionの影響を受けないように分離されている必要があります。

  • Compatibility

    ​ Lambdaには任意のLinuxバイナリおよびライブラリを含めることができます。 これらがコードの変更や再コンパイルなしで動作するように互換性を担保する必要があります。

  • Fast Switching

    古いLambda Functionと新しいLambda Functionを高速に入れ替えられる必要があります。

  • Soft Allocation

    CPU、メモリ、その他のリソースをオーバーコミットできる必要があります。各Lambda Fucntionは、必要なリソースのみを消費し、利用資格のないリソースは消費しません。

これらの評価軸に基づき、環境分離の実現方式として以下のアーキテクチャについて評価を行いました。

  • コンテナ

    各コンテナが1つのカーネルを共有して利用することによるセキュリティの考慮事項や、seccomp-bpfでコンテナから利用できるシステムコールを制限することによる互換性の問題が懸念事項となります。

  • (JVMのような)各プログラミング言語を実行するためのVMによる仮想化

    AWSのサーバーレスプラットフォーム(LambdaやFargate)では任意のバイナリ実行をサポートする必要があるため、この方式は適していませんでした。

  • OS仮想化

    OS仮想化のためのオーバーヘッドとVMの起動時間がネックです。仮想化機能自体の実装が複雑になることで、攻撃を受けるリスクも高まります。

これらの問題から、FirecrackerはKVMを利用しつつ、VMM(Virtual Machie Monitor)に必要最低限の独自実装を利用するという選択肢が取られることになりました。

3 The Firecracker VMM

この章ではFirecrackerの詳細について解説されています。

Firecrackerの実装は、GoogleのChrome OS仮想マシンモニターcrosvmからフォークして、そのコンポーネントの一部が再利用されていることや、KVMを利用することのメリットについて説明されています。

Firecrackerのデバイスモデル

Firecrackerが提供するデバイスモデルについての解説です。Firecrackerは、コンテナとLambda Functionのワークロードに特化しており、限られた数のエミュレートされたデバイス(ネットワークデバイスとブロックデバイス、シリアルポート、部分的なi8042(PS / 2キーボードコントローラー)サポート)を提供します。シリアルおよびi8042エミュレーションの実装は単純です、i8042ドライバーはRustの50行未満、シリアルドライバーは約250行です。ネットワークとブロックデバイスに関してはvirtioを使用しています。Firecrackerでのvirtioブロックの実装全体は、Rustのコード約1400行です。

FirecrackerのREST API

FirecrackerはRESTベースの設定APIを提供しており、APIを通じて ディスク、ネットワーク、シリアルコンソールのデバイスエミュレーション。 また、ネットワークとディスクのスループットを構成することができます。設定のためのインターフェースとしてFirecrackerがRESTを選択した理由について解説されています。

レートリミット、パフォーマンス、仮想マシンの構成について

FirecrackerはREST API経由でMicroVMに公開するメモリの量とコア数を構成し、MicroVMが認識するcpuidビットを設定できます。 また、Firecrackerのブロックデバイスとネットワークデバイスは、APIを介して構成された組み込みのレートリミッターを提供します。これらのレート制限により、1秒あたりの操作数(ディスクではIOPS、ネットワークでは1秒あたりのパケット数)と、各MicroVMに接続されている各デバイスの帯域幅に制限を設定できます。 レートリミットを構成することで

  • コントロールプレーン操作に必要な帯域を確保する
  • 少数のビジーなMicroVMが他のMicroVMのパフォーマンスに影響するのを防ぐ

といったメリットがあります。

セキュリティ

FirecrackerのJailerについての説明等

FirecrackerのJailerはchroot、cgourps、 namespaces、seccomp-bpf等といった技術を利用してMicroVMをサンドボックス環境で起動することで、MicroVMに対して追加レベルの保護を提供しています。

4 Firecracker In Production

AWS Lambdaの裏側で、Firecrackerがどのように利用されているか解説されています。

Lambda実行環境を構成している

  • Frontend
  • Worker
  • Worker Manager
  • Placement Service

といったコンポーネントの役割等が解説されています。これらのコンポーネントの役割についてはこちらのブログで詳しく取り上げているので、良ければ参考にして下さい。

また、私も初見だったのですが、MicroManagerというコンポーネントについても解説されていました。このMicroManagerは事前起動したMicroVMの小さなプールを保持しており、PlacementServiceが新しいLambda実行環境を要求したときに利用しているそうです。Firecrackerが提供する125ミリ秒というVMの起動時間は高速ですが、Lambdaのスケールアップ処理にとっては十分な速度ではありません。VMの起動待ちによってユーザーのリクエストがブロックされることを避けるためにMicroVMを事前起動してプールしておくそうです。普段我々が意識しているLambdaのコールドスタートも

  • MicroVMの起動を伴うコールドスタート
  • 起動済みのMicroVMを利用するコールドスタート

というパターンに分かれると考えて良さそうです。

また、MicroManagerはLambda FunctionとFrontendの間でリクエスト/レスポンスペイロードを仲介しているそうです。Lambdaのカスタムランタイムを実装する場合、環境変数AWS_LAMBDA_RUNTIME_APIから取得したエンドポイントに対して諸々のリクエストを発行しますが、このエンドポイントがMicroManagerなのかもしれません。

この章では他にもLambda実行環境を旧来のEC2モデルからFirecrackerモデルに移行した話なども紹介されていました。まずはAWS内部のワークロードをFirecrackerモデルに移行した後、顧客のワークロードを順次移行していったそうです。移行の過程で

  • 名前解決の結果がMicroVMにキャッシュされない
  • Apache HTTP Clientのバグを引く

といった問題も発生したそうですが、高速かつ安全にEC2モデルにロールバックできるような監視、デプロイ手順のメカニズムが確立されているため、大きな問題には至らなかったそうです。

5 Evaluation

この章ではFirecrackerのパフォーマンス評価について紹介されています。

  • Boot times
  • Memory overhead
  • IO performance

という3つの評価項目について、

  • Firecracker
  • QEMU
  • Intel Cloud Hypervisor
  • 物理マシン

それぞれのベンチマークを計測して比較しています。ざっくり紹介すると、FirecrackerはQEMUと比較するとVMの起動時間(Boot times)が高速で、メモリのオーバーヘッドも非常に小さいという結果が出ています。一方でIO周りのレイテンシーについては他のVMMの方が優れた結果が出ており、まだ改善の余地がありそうです。ただし、IOのレイテンシーについてもLambdaとFargateのニーズを満たすためには十分なレベルに達しており、Firecrackerというは当初の目的を十分に達成していることが分かります。

6 Conclusion

最後に論文のまとめです。Firecrackerや仮想化テクノロジーの将来に対する期待などについて簡単に取り上げつつ終了しています。

まとめ

過去にre:invent2018、2019のAWS Lambda Under the Hoodの動画を見ていたので、割とスムーズに読み進めることができました。個人的にはMicro-Managerというコンポーネントについて新たに知ることができて満足です。今後もFirecrackerの動向を追いかけていきたいと思います。