[レポート][CON406] AWS Fargate と AWS App Runner の詳細を見てみよう #reinvent
はじめに
こんにちは、CX事業本部、re:Invent 2022 現地参加組の田中孝明です。
セッション概要
CON406: A close look at AWS Fargate and AWS App Runner
2015 年以来、AWS は、組織がコンテナ化されたアプリケーションを実行する際の差別化されていない重労働を取り除くのに役立つ複数のサービスを刷新してきました。 Amazon ECS 、 AWS Fargate 、 AWS Elastic Beanstalk 、 AWS App Runner に至るまで、各サービスは基盤となるインフラストラクチャに対するさまざまなレベルの制御を備えた独自の抽象化を提供しています。これらは、すべてのサービスに共通のコア基盤を持つ洗練されたアーキテクチャを提供します。このセッションに参加して、あるサービスから次のサービスへと製品のアイデアがどのように進化したか、およびこの幅広いコンテナー製品をサポートするために基盤となるアーキテクチャがどのように進化したかを学びましょう。
セッション
今日は、サービスのストーリーを少しお話しし、新しいサービスのための製品アイデアがどのように次のサービスへと進化していったか、最初の計算サービスである EC2 から始まり、ブロック内の新しいサービスである App Runner まで、すべてをお話ししたいと思います。
サービスの裏側のアーキテクチャを見てみましょう。その結果、製品のアイデアだけが積み重なっているのではないことがおわかりいただけると思います。 実際のアーキテクチャそのものが、何層にも重なっているのです。新しいサービスは、先代のサービスで築いた基盤の上に構築されています。
このWebアプリケーションのユースケースを使用します。これは、HTTPリクエストに応答する標準的なものです。
一般的に、このようなアプリケーションをどのように実行するかを考えると、VMを用意し、そこにOSをインストールし、好きな言語を選び、アプリケーション名を書き、その上にアセットを配置します。また、スケーリングの冗長性を確保するために、スタックの複数のコピーを実行することもあるでしょう。ロードバランサーを前に置き、デプロイメント・パイプラインを構築することになるでしょう。
AWSの責任共有モデルについて少し話します。 顧客であるお客様は、私たちがインスタンスで行おうとしていることについては、VMを所有し、インスタンス内で実行されるすべてのソフトウェアを所有します。そして、ロードバランサー、Auto Scalingグループ、そしてこれらのインスタンス上のビルドパイプラインを見れます。アプリケーションロードバランサーなどもです。しかし、すべてを結びつけて、適切に設定することは、最終的には顧客の責任です。特に、インフラ管理者ではないお客様からは、「我々自身が管理しなければならないことがたくさんある」と言われます。
2011年、 Elastic Beanstalk が出ました。個々のサービスにアクセスして、それらを組み合わせる方法を学ぶ必要はないというものです。 Elastic Beanstalk は基本的に裏で Cloud Formation テンプレートを作成し、裏ですべてのリソースをデプロイ・プロビジョニングします。 これらのリソースは最終的にあなたのアカウントで実行されるため、責任分界線はまだ変わりません。
2013年〜2014年頃、コンテナが普及し始め、多くのお客様がウェブアプリケーションタイプのユースケースでコンテナ技術を実際に使用するようになりました。
基本的にアプリケーションのレイヤーをOSから切り離します。モノリシックなAMIを構築する代わりに、コンテナとしてデプロイするのです。 コンテナはある程度のリソースの分離を実現するので、実際には複数のアプリ、同じアプリの複数のコピー、あるいは複数の異なるアプリを同じインスタンス内に並列で置くことができます。
ただし、多くの顧客は何百ものインスタンスと何千ものアプリケーションを見る場合、オーケストレーションと配置を行うことになります。 ワークロードの要求があったとき、実際にアプリケーションを起動するために適切なインスタンスの適切な場所をどうやって見つけるか? そのため、コンテナ・オーケストレーターのプロジェクトが数多く立ち上がりました。
Kubernetesは今日、大きな存在です。 これらのオーケストレーターは、簡単なソフトウェアではなく、大規模なサービスや顧客自身がコントロール・プレーンを実行しているのです。
2015年にリリースしたECSでは、基本的にコンテナオーケストレーションのコントロールプレーンを境界の下に戻し、AWS側に責任を持たせるようにしました。インスタンスに ECSエージェント をインストールすると、インスタンスは基本的に私たちのサービスに登録されます。そして、私たちのサービスのAPIをCallするだけで、インスタンス上でコンテナを起動できるようになります。 そして、ロードバランシングやオートスケーリングも実行されます。
ただし、コンテナによってさらに複雑になった問題もあります。
2017年、Fargate というサーバーレスコンテナの提供しはじめました。 顧客は現在のコンテナと通信するのみで、インスタンス層については全く気にする必要がありません。
App Runner は新しいサービスの一つです。
その責任範囲を拡大したのです。自分のアカウントでコンテナを実行する必要はありません。ロードバランサーを実行する必要もありません。オートスケーリング・グループについて心配する必要もありません。デプロイメント・パイプラインについても心配する必要はありません。顧客が責任を負うのは、アプリケーション・イメージと、そのアプリケーション・イメージに含まれるすべてのソフトウェアだけなのです。
では、これによって何ができるようになるのでしょうか?
GitHubにあるソースコードや、ECRにあるビルド済みのコンテナ・イメージから始めることができます。 それをプルダウンしていきます。そして、APIコールを1回行うだけで、create service APIコールが発生する。そして、クライアントがHTTPリクエストを開始するためのURLを取得する。Fargate タスクやコンテナもロードバランサーも見えないし、最後に見えるのはエンドポイントだけで、それに対してリクエストを送れば、魔法のようにすべてがスケールする。
裏側では何が起こっているのでしょうか。 裏で VPC を実行しています。これをサービスVPCと呼ぶことにします。ソースコードから始める場合、我々は基本的にマネージド・ランタイムを所有しており、それを利用できるようにしているので、アプリケーションの言語レイヤーについて心配する必要はありません。私たちが提供するランタイムにレイヤーを重ねるのです。そして、ビルドプロセスに引き込み、アプリのコンテナイメージを生成します。これらを Fargate タスクとしてデプロイします。
顧客のアプリケーションは、顧客の VPC 内のプライベート・データベースなどと通信する必要がある場合、セカンダリ・ネットワーク・インターフェイスを使用してそれを行います。
Fargateについて話す前に、私たちが使っている Firecracker という技術を紹介したいと思います。 ハイパーバイザーの代わりに firecracker をインストールすると、firecracker がマイクロVMと呼ばれるものをスピンアップしてくれます。これは特別なもので、従来のVMとは違います。
このプラットフォームやマイクロVMを使うことで、従来のVMの起動時間は数十秒だったのが、秒単位で起動できるようになったのです。つまり、コンテナを起動するためのリクエストが来たときに、マイクロVMをジャスト・イン・タイムで起動することができるのです。このように、マイクロVMは従来のVMとは異なります。でも、従来のVMとはどう違うのでしょうか?マイクロVMの特徴は、同じベアメタルサーバ上で動作している2つのマイクロVMの間の境界が、従来のVMレベルの分離と同じように行われることです。ですから、同じサーバー上で動作する3つのワークロードをインスタンスレベルで簡単に分離することができるのです。 ゲストOSやゲストカーネルをまったく共有することなく、複数のタスクを実行することができるのです。
エージェントと、アプリケーションを実行するマイクロVM、つまり実際のアプリケーションコンテナで構成されます。
ECSのオーケストレーションの話に移ります。 ECSの仕事は、適切なインスタンスの適切なスロットを見つけ、Fargateエージェントに話しかけて、実際にタスクを実行させることです。
顧客にもご利用いただけるようなコントロールを数多く使用しています。 まず1つ目は、タスクにセキュリティ・グループを使用し、同じテナントで同じサービスのタスク同士であっても、高速通信を許可しないようにすることです。 これらのタスクに入ってくるべき通信は、ロードバランサーとリクエストから流れてくるリクエストだけです。
責任を共有することで、これらのFargateタスクが接続されているセカンダリ EMI は、顧客の VPC、セキュリティグループ、アプリケーションから許可したいアウトバウンドトラフィックの種類を設定する顧客の責任に切り替わります。
そして、これは最近リリースされた機能で、アプリ所有者向けのプライベートサービスエンドポイントを発表しました。
プライマリENIを介したベアメタルインスタンス間の通信は許可していません。唯一許可されているのは、エージェントがECSやコントロールプレーン、イメージプルなどに対して行う通信で、エージェントがセキュリティグループを制御する必要がある場合などです。
Firecracker の利点の1つは、複数のテナントを同じシートに安全に配置できることで、実際に複数のテナントのタスクを複数回配置できます。 ただし、コンテナの境界が十分に安全であるとは信じていません。マルチテナント分離のためです。
タスクのセキュリティポストを維持し、安全な境界線に複数のタスクを置かないという選択をしました。それぞれのマイクロVMには独立したネットワーク・インターフェイスがあり、タスクは同じネットワーク・インターフェイスを通じて通信することはなく、それぞれ専用のENIを持ち接続されています。
エントリーポイントは、フロントエンドサービスです。 タスク管理は、タスクAPIやタスク定義API、クラスタAPI、サービスAPIなどがあります。
ECSは、基本的にはスタック全体をコピーするのではなく、地域ごとにそのスタックのコピーを実行する、ということをやっていました。 完全に独立しているのです。これは、あるリージョンで障害が発生した場合、その影響が他のリージョンに波及しないようにするという精神に基づくものです。
地域内では、スタックや地域のコピーを1つだけにしておくことはよくありません。リージョン全体を持っていかれるのは困ります。そこで、セルラーアーキテクチャという考え方があります。
App runner では、セル内の各コンポーネントが複数の AZ にまたがってストライピングされています。 ある地域には、セルごとに複数のVPCを走らせます。透過的な任意のセルに割り当てられます。 そして、1つのVPCを見るとバランサー、Fargateタスクなど、すべてのコンポーネントが AZ 間でストライプされています。
私たちはコンテナ・アプリケーションをホスティングするための非常に豊富なポートフォリオを持っているということです。 しばしば、アプリケーションにどのサービスを使うか決めるのに戸惑うことがあります。 それぞれのサービスが提供してくれる抽象度の違いを理解することは重要で、こういった質問に対する私の経験則は、常に最も抽象度の高いサービスから始めることです。 そこで実験を始めて、抽象度の高いサービスがうまくいかない具体的な理由が見つかった場合にのみ、スタックを下げていくようにします。
所感
アプリケーション開発基盤の変遷から責任範囲、要素技術など非常に濃いセッションでした。App Runner を使っている上であまり意識しないところの裏側の実情を聞けたりするのでセッション公開時には是非見ていただきたいです。