re:Invent 2024: AmazonECSチームが語る高可用性とレジリエンスの実現方法
はじめに
海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!
📖 AWS re:Invent 2024 - Deep dive into Amazon ECS resilience and availability (SVS409)
この動画では、週に25億タスクを処理するAmazon ECSの高可用性とレジリエンスを実現する設計思想と実装方法について解説しています。Availability Zone、Cell、Regionという3つの分離単位を活用したアーキテクチャや、Static Stabilityの概念に基づくContainer Restart機能、Non-blocking I/Oの重要性など、具体的な実装手法を詳しく説明しています。また、Correction of Errors(COE)プロセスを用いた障害からの学習と改善の仕組みや、2022年のAWS Fargateの障害事例から得られた教訓など、Amazon ECSチームの実践的な運用ノウハウも共有されています。
※ 画像をクリックすると、動画中の該当シーンに遷移します。
re:Invent 2024関連の書き起こし記事については、こちらのSpreadsheet に情報をまとめています。合わせてご確認ください!
本編
Amazon ECSの概要と本セッションの目的
おはようございます。本日はお時間を取っていただき、ありがとうございます。Re:Inventへようこそ。私はMalcolm Featonbyと申します。Server Listening Containers組織のSenior Principal Engineerを務めております。そして私はMaish Saidel-Keesingです。Senior Developer Advocateを務めております。まず確認させていただきたいのですが、皆様、声は届いていますでしょうか?ロンドンの皆様、サムズアップをお願いします。はい、ありがとうございます。
このトークがどのように始まったのか、少し背景をお話しさせていただきます。各サービスチームでは、リーダーシップ、Product Manager、Architect、ソフトウェア開発マネジメントと週次のミーティングを行い、メトリクスやサービスの課題、うまくいっていること、いっていないこと、改善点などについて話し合っています。あるミーティングで、Malcolmが顧客との対話について言及し、Amazon ECSがどのように構築されているか、その背景にある耐障害性や方法論について議論したと話しました。
私は彼にこのような対話を定期的に行っているのか尋ねたところ、実際にこのような1対1の顧客ミーティングを頻繁に行っているとの回答がありました。Amazonでは、ワンオフの対応はスケールしないため、後ほど説明する「メカニズム」というものを好んで使用しています。そこで私は、この内容をRe:Inventで話してみてはどうかと提案しました。昨年、第1回目のバージョンを実施し、そして今回は、この1年間でAmazon ECSにリリースされた新機能や新しい要素を加えた新バージョンをお届けすることになりました。
本日のアジェンダについてご説明します。これは400レベルのセッションですので、コンテナとAmazon ECSの基本的な概念をご理解いただいていることを前提としています。エキスパートである必要はありませんが、これらの基本概念は理解しておく必要があります。あまり詳しくない方のために、まずAmazon ECSとは何か、私たちのサービスが何をするのかについて簡単にご紹介します。その後、Malcolmが、私たちがどのようにサービスを構築し、可用性を確保し、可用性を考慮した設計を行い、運用メカニズムと文化をどのように活用して効率的に機能させているかについてお話しします。最後に、私たちがこれらのメカニズムと方法論を活用して、サービスや障害から継続的に学び、改善を重ねている方法についてお話しします。
Amazon ECSの特徴と利用状況
Amazon ECSは、AWSのネイティブなコンテナオーケストレーションサービスです。今年、LambdaとAmazon EKSと共に10周年を迎えました。お客様は、すでにお馴染みのAWS API、ツール、コンソールを使用してAWSクラウド上でコンテナワークロードをプロビジョニングできます。新しいことを学ぶ必要はありません。これらのコンテナは、さまざまなコンピュートリソース上でプロビジョニングできます:独自の仮想インスタンスをプロビジョニングしたい場合はAmazon EC2、コンピュートリソースの管理とメンテナンスを私たちに任せたい場合はAWS Fargate、そしてハイブリッド環境で実行している場合はAmazon ECS Anywhereを使用することで、同じコンソールと方法論を使用しながら、お客様のデータセンターやサードパーティのデータセンターでコンテナをプロビジョニングすることができます。
Amazon ECSは世界中の34のリージョンにデプロイされています。私たちはこれを基盤サービスと呼んでいます。新しいリージョンを立ち上げる際、Amazon ECSは他のサービスが利用する実際の基盤ブロックの一部となっています。毎週、これらすべてのリージョンで24億以上のタスクが起動されています。AWSクラウドを利用してコンテナを実行したいと考えるお客様の65%が、まずAmazon ECSを選択します。そしてそのうちの70%以上が、EC2インスタンスの管理が不要で、Amazonとのシームレスな統合が可能なAWS Fargateを選択しています。
お客様は様々な業界や分野でAmazon ECSを活用しています。 これには本番環境での重要なワークロード、銀行業務など、多岐にわたります。私たちのWebサイトでは、お客様が自社の製品開発や顧客サポートにAmazon ECSをどのように活用しているかについての事例や活用例をご覧いただけます。
Amazon ECSはお客様だけでなく、Amazon社内でも広く使用されています。多くの当社サービスがAmazon ECSを使用して構築されており、まさに基盤サービスとなっています。Amazon ECSが準備され、デプロイされていない状態では新しいリージョンを立ち上げることができません。なぜなら、その上に構築された全てのサービスがAmazon ECSに依存しているからです。例えば、Amazon SageMaker、Amazon Lex、Amazon Polly、AWS Batch、Amazon.comのレコメンデーションエンジンなど、多くのサービスが、その使いやすさから今日も引き続きECSを利用しています。
高可用性とレジリエンスを実現するAWSの基本原則
お客様からよくいただく質問の一つに、高可用性と高い回復力を実現するためにECSをどのようにアーキテクチャ設計すべきかというものがあります。本日は、私たちが可用性と回復力を実現するために使用しているパターンをいくつかご紹介したいと思います。これらのパターンについて深く理解していただくことで、ECS上でサービスを構築する際に、お客様の要件に合った可用性を実現できるようになることを目指しています。
先に進む前に、AWSで可用性の高いサービスを構築する際の基本的な前提と原則についてお話ししたいと思います。最初に、当社のCTOであるWerner Vogelsが話している考え方があります。それは、可用性が高く回復力のあるサービスを構築するためには、サービスの障害は自然な出来事として受け入れなければならないということです。つまり、私たちは障害を当たり前のこととして設計し、運用しているのです。この考え方は、私たちが採用している全てのパターンに通じています。物事は壊れるものだということを受け入れ、それに対して計画を立て、設計し、運用することができていれば、それは実際には問題ないという考え方なのです。
Availabilityについて話すとき、私たちが実際に意味することを明確にしておく必要があります。私たちにとってAvailabilityとは、システムが有用な作業を実行できる能力のことです。これは本質的に確率の指標です。100件のリクエストを処理する場合、理想的な世界では、その100件すべてが顧客に対して有用なレスポンスとして正常に処理されるはずです。リクエストを処理できない場合、それがAvailabilityを低下させることになります。有用なレスポンスが95件しか返せなかった場合、Availabilityは95%となります。私たちの目標は、すべてのリクエストが有用なレスポンスを得られる、Availability 100%という理想の状態に到達することです。
これを実現するには、レジリエントなサービスを設計する必要があります。レジリエンスとは、障害を吸収し、その障害から素早く回復するサービスの能力です。障害は必ず発生するものと受け入れた上で、100%のAvailabilityという理想に到達するためには、障害が発生した際にできるだけ早く回復できるようにサービスを設計する必要があるのです。
ECSおよびすべてのAWSサービスが、必要なAvailabilityを実現するために構築している基本的な要素があります。その最初のものがAWS Regionです。世界中に34のAWS Regionがあり、これらはAWSの地理的な存在を表しています。AWS Regionで興味深い点は、アーキテクチャの観点から「Shared Nothing」というコンセプトを採用していることです。AWS Regionは他のAWS Regionとは完全に独立しており、互いを認識していません。これは意図的な設計であり、私たちはこれをアーキテクチャ設計の一部として活用しています。
AWS Regionは、各リージョン内にAvailability Zoneを持っています。 最低でも3つのAvailability Zoneがあり、大規模なリージョンではそれ以上あります。Availability Zoneは、私たちが障害ゾーンまたは故障ゾーンと呼ぶものを表す、有用なインフラストラクチャの構成要素です。
Availability Zoneは1つ以上のデータセンターで構成されており、リージョン内で地理的に近接しているため、あたかも同じデータセンターのように感じられます。多少のレイテンシーの違いはありますが、概ね同じように機能します。重要なのは、それぞれが地理的に十分に離れており、ネットワークや電源を共有していないことです。すべてのAvailability Zoneは冗長化されたネットワークと電源を持っています。自然災害や停電が発生した場合でも、Availability Zone間で相関した障害は発生しにくく、それぞれが独立して障害を起こすと考えられます。このRegionとその中のAvailability Zoneという概念が、高度にレジリエントなサービスを構築するための基本的な構成要素となっています。
Amazon ECSのアーキテクチャと可用性確保の仕組み
それでは、ECSのアーキテクチャについて詳しく見ていきましょう。 可用性について考える際、私たちは障害の種類をいくつかの次元で分類することができます。発生し得る障害の種類を分類すると、以下のようになります。それぞれ個別に見ていきましょう。1つ目はインフラストラクチャで、これは先ほどAvailability Zoneで説明した、基盤となるハードウェアやネットワークなどの障害です。2つ目はソフトウェアで、これは私たちが常にデプロイしているものを指します。継続的にデプロイを行う中で、避けられない不具合やデプロイメントの問題が発生することがあります。3つ目はスケールで、これはサービスに影響を与える可能性のある外部要因による振る舞いを指します。
Amazon ECSのコントロールプレーンは、ワークロードを管理するソフトウェアの一部です。Amazon ECS上でServiceやTaskを実行する場合、コントロールプレーンがスケジューリング、プロビジョニング、デプロイメントを行い、そのTaskの管理と維持を担当します。Amazon ECSのコントロールプレーンは34のAWSリージョンすべてで提供されており、Shared Nothingアーキテクチャを採用しています。あるリージョンのAmazon ECSインスタンスは、他のリージョンのAmazon ECSインスタンスの存在を一切認識せず、Amazon ECSは少なくとも3つのAvailability Zoneに存在します。
私たちは、Static Stabilityと呼ばれる概念を用いて、このShared NothingアーキテクチャとAvailability Zoneを活用しています。Static Stabilityとは、障害が発生した場合でも、外部からの介入や対応なしに機能し続けることができるサービスの特性を指します。これはDevOps エンジニアの観点から見ると理想的です。障害が発生するたびに対応に追われるのは避けたいものです。バックグラウンドで必要な修正を行っている間も、サービスが継続して機能することが望ましいのです。
Amazon ECSでこれを実現する方法の1つが、Availability Zone全体にわたる事前スケーリングです。これにより、1つのAvailability Zoneが障害を起こしても、残りの2つのAvailability Zoneでトラフィックを継続して処理できます。具体的には、ピーク時の150%までサービスを事前にスケールさせます。つまり、各Availability Zoneには、そのリージョン全体のピーク時に必要な容量の50%を確保しています。2つのAvailability Zoneの場合、各ゾーンに100%の容量が必要となり、より大きなフットプリントが必要になります。Availability Zoneの数が増えれば、各ゾーンのフットプリントを減らすことができます。この方式の利点は、事前スケーリングを活用してサービスを運用できることです。つまり、あるAvailability Zoneが障害を起こしても、Static Stabilityにより、何も対応する必要がなく、ピークトラフィックに対して100%のスケールを維持できます。
Amazon ECS上でシステムを構築する際、お客様もこの特性を活用することができます。 Amazon ECSでソフトウェアをデプロイする場合、通常はECS Serviceを作成し、そのECS ServiceがTaskをプロビジョニングします。この例では、キャパシティプロバイダーとしてAWS Fargateを使用しています。お客様がAWS Fargateを選択する理由は、そのサービスの利点にあります。つまり、EC2インスタンスの運用や管理の負担を気にする必要がないということです。
このモデルでは、ECS Serviceが単一のAvailability Zoneに単一のタスクをプロビジョニングしているのが分かります。これは明らかにHigh Availabilityではありません。ハードウェアに障害が発生したり、Availability Zoneが停止したり、デプロイを行ったりした場合に、何らかの形で停止が発生してしまうからです。 私たちが目指すのは、需要に応じてServiceをスケールできる状態です。この例では、ECS Serviceの需要に対応するために3つのタスクインスタンスが必要だと判断し、それらをAvailability Zone全体に分散させています。AWS Fargateを使用する場合、指定されたサブネット全体に自動的に分散配置するアルゴリズムが使用されます。ECS Serviceを作成する際に1つ以上のサブネットを指定すると、ECSは指定されたサブネット間で最適な分散配置を行うよう努めます。
ここで、可用性を確保するためのソフトウェアデプロイメントの管理方法についてお話ししましょう。 先ほどMaishが説明したように、私たちは週に25億のタスクをプロビジョニングしています。これは非常に大規模なプロビジョニングとワークロードの管理です。私たちは、この大規模な環境で継続的なデプロイを行いながら、それを管理できる体制を整えたいと考えています。Amazon ECSは多くのソフトウェアスタックで構成される大規模なサービスであり、この規模でバグが多くのお客様に影響を与えることなく、継続的にサービスをデプロイできるようにしたいと考えています。
これを実現するために、私たちはECSのコントロールプレーンをCellと呼ばれる単位に分割し、Cellular Architectureを採用しています。Cellular Architectureとは、特定のRegionの3つのAvailability Zoneにまたがって配置されたECSコントロールプレーンの完全なコピーを、複数回デプロイすることを意味します。つまり、1つのRegionで複数のECS管理レイヤーを実行しているということです。 そして、その前面に薄いProxyレイヤーを構築します。このProxyレイヤーのポイントは、できるだけシンプルで単純な作りにし、基本的なルーティングで特定のCellを選択するだけの機能に留めることです。単一障害点とならないよう、完全にステートレスである必要があります。
現在、ECSの前面にあるProxyレイヤーは、シャーディングキーに基づいてルーティングを行います。このシャーディングキーはECS Clusterです。トラフィックが入ってきてECS Clusterが作成されると、特定のCellに配置され、そのCellがそのClusterの生涯にわたって責任を持ちます。これは非常に強力な考え方です。なぜなら、障害を封じ込めることができるからです。特定のパーティションにデプロイの問題やスケーリングの問題が発生しても、そのパーティションは特定のRegionにおけるECS全体の一部分にすぎません。
週25億のタスクという規模を考えると、これは途方もなく大きなサービスです。私たちは、この回復力と迅速な復旧能力を確実に提供したいと考えています。パーティション化することで、より小さなフットプリントで管理できます。データベースレベルまでパーティション化することで、データベースの復旧が必要な場合でも、Region全体ではなく、そのパーティションのデータベースだけを復旧すればよいことになります。これにより、復旧が早くなり、ソフトウェアのデプロイやロールバックも、扱うフットプリントが小さいため迅速に行えます。Cellular Architectureは、障害の影響範囲の制限という観点で、真の回復力と可用性の両方のメリットを提供します。
Amazon ECSの自動化とデプロイメントプロセス
このアーキテクチャをどのように活用できるか、お話ししましょう。先ほど申し上げたように、フロントエンドで使用しているプロキシ、つまりルーターは、ECS Cluster IDを使用しています。ECSに詳しい方々 - これは400レベルのセッションなので、皆さんそうだと思いますが - ご存知の通り、ECS APIではほぼすべての操作でCluster IDをキーとして使用します。これは、リクエストを適切な基盤のパーティションにプロキシして転送するために使用されているためです。
これはアーキテクチャを設計する上で大きな利点があります。なぜなら、私たちのアーキテクチャが提供する基盤となる可用性の構成要素を活用できるからです。Cluster IDを使用して、ソフトウェアスタックを特定のAmazon ECSの可用性スタックに合わせることができます。例えば、顧客がyellow、red、pinkのクラスターを持っている場合、それぞれのソフトウェアをそれらのクラスターにデプロイします。これらのクラスターはパーティション分割され、そのソフトウェアスタックは、特定のクラスターを管理することに特化した管理レイヤーに分割されます。つまり、もし私たちが意図せずにあるクラスターに影響を与えるソフトウェアをリリースしたとしても、その特定のクラスターにのみ影響し、他のクラスターには影響しないということです。
スケールについて、そしてスケールのための設計についてお話ししましょう。先ほど25億のタスクという非常に大きな数字について触れました。サービスをスケールする典型的な方法として、スケールアップとスケールアウトがあります。スケールアップとは文字通り、より大きなものを購入すること - より大きなハードウェアを導入したり、特定の垂直方向でより多くのハードウェアを導入したり、より大きなデータベースを使用したりすることです。スケールアップの課題は、ある程度無制限だということです。この道を進み続けることはできますが、ある時点で、物事がスケールする次元について考えることが難しくなります。サーバーの数が問題になってくるからです。このようにサービスをスケールすると、障害が発生する次元が増加し始めます。特定のGossipグループ内のサービス数が非常に大きくなり、突然Gossipグループが機能しなくなってしまいます。
私たちが通常行うのは、スケーリングのメカニズムとしてパーティションとCellsを使用することです。その利点は、特定のパーティションサイズにスケールを制限できることです。例えば、この特定のリージョンで100個のものを実行している場合、10個のCellsを導入し、それぞれのCellsが10個の作業を処理できるようにすることができます。これにより、各Cellがどれだけの作業を処理できるかが分かり、110個必要になった場合は、単にCellを1つ追加すればよいことが分かります。つまり、効果的にスケールアウトのメカニズムを使用しているのです。Amazon ECSをスケールするために、私たちはより多くのパーティションを構築します。これにより、ソフトウェアの複雑さという観点からアーキテクチャ全体の複雑さが軽減されます(ただし、これに関連する運用上の複雑さは存在します)。また、サービスを成長させるための境界のある単位を持つことができます。
もう一つの重要な側面は、サービスを限界点までスケールテストする能力です。週に25億のタスクをプロビジョニングするサービスのスケールテストを行うことは、ほぼ不可能でしょう。実質的に本番環境の負荷をシミュレートする必要がありますが、そのスケールでは現実的ではありません。 パーティションを使用する利点の1つは、任意のパーティションで効果的に限界までスケールテストできることです。プリプロダクション環境で、10までスケールアップするパーティションを作成し、それを12まで実行して、どのように破綻するかを確認できます。これにより、本番環境の負荷でテストを行うことなく、基盤となるアーキテクチャが極端な負荷下でどのように動作するかについて深い洞察が得られます。
Amazon ECSを使用してCellularアーキテクチャを実現するためのメカニズムがいくつかあります。これはその一例です。このパターンでは、Routerとして機能するAmazon ECSサービスがあり、その下に2つのAmazon ECSサービスがあり、それらにRoutingすることでCellularアーキテクチャを実現しています。Cellularアーキテクチャの特徴は、可用性の面では非常に強力ですが、運用面やコンピューティングインフラの使用効率の面ではコストがかかります。重要なコンポーネントにのみ適用すべきもので、すべてのアーキテクチャに適しているわけではありませんが、特定のアーキテクチャには最適なソリューションとなります。AWSのベストプラクティスには、Amazon ECSのCellularアーキテクチャを構築するためのメカニズムやリファレンスアーキテクチャの例が用意されています。
この情報については、後ほど個別にご相談いただければと思います。
では、自動化を通じたResilience(回復力)についてお話ししましょう。真のResilienceを実現するには、できるだけ多くのことを自動化したいと考えています。すでにいくつかの概念について説明しました:Availability Zone、Cell、そしてRegion単位での分離です。お気づきかもしれませんが、これによってAvailability ZoneとCellのマトリックスが作成されます。これにより、デプロイメントユニットを非常に小さな単位に限定することができます。 変更をデプロイする際、単一のCellの単一のAvailability Zoneに対してその変更をデプロイします。Rolling Deploymentを使用しますが、これはAmazon ECSのデフォルトのデプロイメントメカニズムです。私たちにとって最も有用で、ベストプラクティスと考えているため、デフォルトとして設定しています。
この例では、単一のCellの単一のAvailability Zoneに18台のHostが配置されています。Rolling Deploymentは、そのHostの一部に対して展開されますが、最初はそのCellとAvailability Zoneのみに限定されます。これにより、その変更に対する信頼性を高め、継続的に変更をデプロイすることができます。Amazon ECSは大規模なサービスで、私たちは継続的にデプロイを行っています。お客様からAmazon ECSのデプロイメントやメンテナンスのスケジュールについて質問されることがありますが、答えは「常時」です。Amazon S3やAmazon EC2など、多くのAWSの基盤サービスに依存する大規模なサービスなので、文字通り今もデプロイを行っています。お客様のニーズに応えるためのResilienceと可用性を実現するには、このようなモデルが必要なのです。
このパターンを使用してRolloutを行うことで、変更に対する信頼性を構築していきます。最終的に、その変更は単一のCellの単一のAvailability Zone内に完全に展開されます。それが問題ないと判断されれば、 次のAvailability Zoneにその変更をデプロイし続け、 そのCellのすべてのAvailability Zoneに変更をデプロイしてから、次のCellに移ります。 デプロイメント自体は継続的なケイデンスで行われ、そのソフトウェアの変更を継続的にRolloutしています。
あるAvailability Zoneでデプロイメントの失敗が発生した場合でも、私たちは一度に1つのAvailability Zoneにデプロイし、信頼性を確認しながら進めているため、150%のキャパシティスケーリングを活用できます。これにより、問題のあるAvailability Zoneを切り離して素早くフェイルアウトさせることができ、優れた回復力を実現できます。150%にスケールしているため、オーバースケール状態であり、他の2つのCellでソフトウェアが正常に動作していることが分かっているので、問題のあるAvailability Zoneから離脱してほぼ瞬時に回復し、エンジニアが問題の調査を行うことができます。
サービスに対して継続的なモニタリングを実施しており、Bake timeと呼ばれる考え方を採用しています。変更をデプロイする際、リージョン内の特定のデプロイメントステップでその変更をベイクし、モニタリングを行います。Bake timeという名称は少し誤解を招くかもしれません。というのも、実際には時間ベースではなく、ソフトウェアの動作に基づいているからです。私たちの規模である毎秒数百万TPSでは、異常な動作なく成功的な呼び出しが行われていることを確認するためにモニタリングを行います。成功を確認できたら、その特定の変更を良好とみなして次のステップに進みます。大規模な環境では、大量のデータをすぐに得られるため、これらの判断を迅速に行うことができます。
失敗が発生した場合は、すぐに前のリビジョンに戻します。 自己完結型のユニットでデプロイを行っているため、非常に素早くロールバックできることが利点の1つです。Cellは非常に小さな単位であり、Cell内の特定のAvailability Zoneへのデプロイは、その小さな単位の3分の1に過ぎないため、迅速に是正措置を取ることができます。
また、Amazon ECSのAvailability Zone回復力を継続的にモニタリングしているのも特徴の1つです。今年導入したAutomated weigh awayと呼ばれる機能をリリースしました。常時、各Availability ZoneでのAmazon ECSの可用性をモニタリングしており、いずれかのAvailability Zoneで異常な動作が確認された場合、自動的にそのゾーンからトラフィックを切り離します。これはロードバランサーには影響しませんが、実行中のワークロード、デプロイメント、プロビジョニング、スケジューリング、スケーリングには影響します。なぜなら、私たちの目標は可能な限り100%の可用性を維持することだからです。
これは、異常な動作を検知したら直ちに、他のAvailability Zoneにあるコントロールプレーンスタックを使用してプロビジョニングと配置を継続することを意味します。また、デプロイメントがこれらの変更の影響を受けないよう、それらのAvailability ZoneでのAWS Fargateの配置を優先します。 その副作用として、サービスの分散が不均等になる可能性があります。先ほどの例では、あるサービスに3つのタスクがありましたが、デプロイメント中にAvailability Zoneのweigh awayが発生した場合、3つのタスクのうち2つがAvailability Zone 2に、1つがAvailability Zone 1にデプロイされるという不均衡な状況になる可能性があります。
先月、AZ Rebalanceという新機能をリリースしました。Amazon ECSの設定の一部として、サービスに対して継続的なリバランスの必要性を指定できるようになりました。Amazon ECSは、指定されたサブネットとAvailability Zoneの分散状況に対して、タスクの分布を監視し、不均衡な状態を検知します。不均衡を検知すると、自動的に是正措置を講じます。Amazon ECSは、マネージドサービスにおいて「Start Before Stop」というメカニズムを採用しています。既存のタスクを停止する前に、必ず新しい代替タスクを起動することで、サービスの可用性を維持するために必要な数のタスクを確実に保ちます。
Amazon ECSの新機能と継続的な改善
この具体的なケースでは、Amazon ECSは特定のAvailability Zoneでオーバーサブスクライブされているタスクを特定します。その後、十分なタスクがないAvailability Zoneで新しいタスクを起動し、そのタスクが正常であることを確認してから、オーバーサブスクライブされているAvailability Zoneのタスクを終了させ、バランスの取れた状態に戻します。これは、お客様が面倒な作業を心配する必要がないよう、ベストプラクティスをマネージドサービスに組み込むという私たちの考えを具現化したものです。お客様は単にサービスを使用し、フラグを設定するだけで、私たちがサービスの可用性を最大限に保つよう努めます。
今年初めに導入したもう一つの機能は、ソフトウェアの実際のデプロイに関連する、レジリエンスと可用性に関するものです。コンテナでよくある経験として、タスク定義でイメージにLatestタグを使用することがありますが、Amazon ECRイメージのこれらのタグは、リポジトリの設定によって変更可能である場合があります。これは問題となる可能性があります。なぜなら、Latestタグを使用している場合にロールバックすると、実際には最新バージョン(最も新しいもの)にロールバックしてしまい、期待する安定性が得られない予期せぬロールバック動作が発生するためです。
この問題に対処するため、Amazon ECSはDeployment Version Stabilityという機能を導入しました。Amazon ECSで新しいデプロイメントを作成する際(既存のサービスの更新や新規作成時)、Amazon ECSはイメージに関連するSHAと全ての設定をスナップショットとして保存し、デプロイメントIDと関連付けます。これにより、スケールアップ時には常にサービスの最新スナップショットにスケールアップし、ロールバック時には以前の既知の正常なバージョンにロールバックすることが保証されます。これにより、常に最も安定したバージョンのソフトウェアをデプロイできることを保証します。ロールバックしても同じ問題が発生するという最悪の状況を避けたい場合、この機能は非常に有用で望ましい動作となります。
可用性に関する構造とアイデアについて説明してきましたが、次はレジリエンスの目標を達成するために活用している静的安定性に関するアイデアについてお話しします。その最初の例がContainer Restartという概念です。静的安定性を実現する上で興味深い点は、可能な限り処理をローカライズしたいということです。Amazon ECSタスクが失敗して終了した場合、ECSはプロビジョニングとプレイスメントのプロセスを実行する必要があり、AWS Fargateの場合はキャパシティの確保も含まれます。
サービスで異常な動作が発生した場合、プロビジョニングの一部が実際に破損し、この異常な動作の影響を受けている可能性があります。理想的な状況では、現在のインスタンスにおけるローカルな安定性、つまりStatic stabilityを維持したいものです。Amazon ECSは今年初め、Local container restartという概念を導入しました。これにより、コンテナが失敗した場合にそのマシン上で再起動するように、タスク定義で設定できるようになりました。これは、例えばメモリ不足による障害の後にコンテナが再起動でき、再プロビジョニングが可能な場合、プロビジョニングされたタスクに戻るために制御プレーン全体を経由する必要がないという点で有益です。
このアプローチは、プロセスのプロビジョニングがサブセカンドで実行できるため、可用性の面でずっと優れています。制御プレーンに戻る場合、状態のドリフトと状態の調整という一連のプロセスが発生し、可用性が低下する可能性があります。このLocal container restart機能の検討をお勧めします。
今年、お客様から指摘され影響を受けたもう一つの課題は、Blocking I/Oの問題です。ワークロードの依存関係を十分に認識することが非常に重要です。私たちAmazon ECSチームは、アーキテクチャレビューの際に、依存関係とその障害が可用性に与える影響について慎重に検討しています。サービスを設計する際は、特にI/Oに依存している下流の依存関係が失敗した場合の対応を考慮する必要があります。
一部の障害はそのままの状態を受け入れざるを得ません。例えば、データベースと通信できない場合、それはサービスが単純に不健全であることを意味するかもしれません。しかし、これは必ずしも当てはまるわけではありません。例えば、ロギングの場合、Dockerのデフォルトの動作はBlocking I/Oを使用しており、これがサービスの可用性に悪影響を及ぼす可能性があります。つまり、標準的なinfoメッセージをログに記録する場合でも、下流の依存関係が利用できず、ログを書き込めない場合、サービス全体が停止してしまう可能性があります。Amazon ECSはAWS Logsのデフォルト設定として非ブロッキングI/Oをサポートしており、可能な限りこれを使用することを推奨しています。
厳しく規制された業界では、ログファイルを絶対に確保する必要がある場合、非ブロッキングI/Oが使用できない場合があります。これが自分たちにとって適切なアプローチかどうかを十分に検討してください。私たちの内部では、大多数のサービスではそれらのログは必要ないことがわかっています。ログが取れないためにサービスが機能できなくなるよりも、サービスが継続して機能する方が重要だと考えています。基盤となるソリューションの可用性を向上させるため、可能な限り非ブロッキングI/Oを使用するように設定を見直すことをお勧めします。
AmazonのOperational Excellenceと継続的改善プロセス
それでは、私たちの継続的改善プロセスについて説明するため、Maishに引き継ぎたいと思います。ありがとうございます、Malcolm。 画面に表示されているのは、私たちが「Flywheel」と呼んでいるものです。Amazonはあらゆる場面でFlywheelを活用しています - 各チーム、各製品にFlywheelがあり、複数のチームが異なるFlywheelを持っています。これはUptimeのFlywheelで、Operational Excellenceを活用して継続的な改善を行う方法についてお話ししたいと思います。私たちは定期的にサービスに対してChaos ExperimentやGame Dayを実施し、サービスがどのように障害を起こす可能性があるかを理解しています。
実際に私たちがこれを定期的に行う方法を説明させていただきます。まず、準備フェーズから始まります。チームと一緒に座って、意図的に何かを壊す実験を計画します。これは、本番トラフィックのないAvailability Zone内のテスト環境を使用することで、お客様への影響を最小限にするか、まったくない形で実施します。サービスの動作を理解するためのシナリオを実行し、ログ、アラート、自動復旧手順に関する期待値を設定します。
次に検出フェーズに移り、期待通りの結果が得られたかを確認します。サービスから適切なシグナルを受け取れているかをチェックします。私たちが「Flying Blind(盲目飛行)」と呼ぶ状況、つまり何かが起きているのに、その根本原因を理解するための情報やメトリクス、ログが何もない状況は避けたいと考えています。このような状況では障害からの復旧と解決が非常に困難になるため、実験中に適切なシグナルを得られることを確認します。
対応フェーズでは、特定の障害時に適切な人々に連絡が行き、自動化された手順が意図した通りに機能したかを確認します。手動での介入を最小限に抑え、自動化を最大限に活用して、可能な限り短時間で障害から復旧することを目指しています。学習フェーズでは、チーム全体で事後分析を行い、すべてが期待通りだったか、あるいはサービスについて新しい発見があったかを理解します。 これらの知見を活用して、メトリクスの改善、アラートシステムの調整、インシデント発生時の適切な人員の関与など、プロセスの改善を行います。
この学習により、サービスのアーキテクチャを見直し、システムの他の部分への悪影響を防ぐために別のMicroserviceに分割するといった対応が必要になることもあります。学習フェーズの一環として、Correction of Errors(COE)プロセスを実施します。これはAmazonの全チームで標準的に行われている問題の特定と修正のためのプラクティスです。具体的なアクションアイテムを個人に割り当てることで当事者意識を高め、週間2.4億タスクという規模で直面する課題は他のサービスにも関連する可能性があるため、Amazon全体で知識を共有するために活用しています。
Correction of Errors(COE)は責任追及のためのものではないということを理解することが重要です。特定の個人やチームを非難するために使用することは決してありません。代わりに、継続的な改善のための前向きな学びの機会として扱います。単なる「設定ミス」や「オペレーターのミス」として片付けることはせず、常に防ぐことができたはずの要因を探り、それらの知見をサービスの改善に活かしています。
COEは特定の状況で実施されます。主に、顧客に影響が及ぶ場合、つまり顧客がサービスの停止や品質低下を経験した場合です。また、不足しているテストケースなど、手順上のギャップが特定された場合にも実施します。
COEを使用するということは、私たちのサービスにおける特定のユースケースについて十分な理解が得られていなかったことを意味し、今後さらなる改善のためにより深く理解する必要があるということです。また、顧客が私たちの想定していなかった方法でサービスを使用する、というミスユースケースの場合もあります。このようなケースについてもCOEを実施し、そのユースケースをカバーして改善点を見出し、顧客にとってより良いものにすることができます。
この学びは、組織内のAmazonサービスチーム間で、そして他のチームとも共有していきます。COEはどのようなものでしょうか? COEは2つの異なるパートで構成されています。1つ目は、通常2〜4ページの文書となるサポート情報です。これには以下のトピックが含まれます:顧客視点で何が起きたのかを正確に説明するインシデントの要約、何人の顧客が影響を受けたのか、Amazonで注文できなかったのか、Amazon ECSタスクを起動できなかったのかを示す影響範囲、そしてメトリクスに基づいて何が起きたのかを示すタイムラインです。
タイムサイクルに基づいて、いつ問題が発生し、いつ問題を特定し、いつ解決したのかというタイムラインを理解し構築することができます。これにより、問題への対応や復旧にどれだけ迅速に対応できているかを測定できます。メトリクスでは、ドロップされたパケット数や失敗したタスク数など、すべてのログを確認し、サービスのモニタリングと運用の一環として受け取るべき情報を把握します。インシデントに関する質問では、なぜこれが起きたのか、何が問題だと理解したのか、どのように解決したのか、どのチームが関与したのかを扱います。
最後のパートは修正の部分で、5 Whysを使用した学習アクションです。これは非難することなく学習するための非常に優れた方法で、実際の問題点を掘り下げていきます。オペレーショナルエラーやオペレーターエラーは決してRoot Causeにはなりません - 必ず寄与する要因があるものです。なぜオペレーターエラーを防ぐための自動化がなかったのか?なぜそのエラーがそれほど多くのホストに対して実行されたのか?Lessons Learnedは特定の障害から学んだことを示し、Action Itemsは修正のために担当者と期限を決めて割り当てられます。これらは即時の修正項目である場合もあれば、サービス改善のためのロードマップ項目である場合もあります。
Amazon ECSの障害事例と学び、そして今後の展望
具体的な事例として、Amazon ECSに関連する AWSでの2つの障害についてご説明します。1つ目は2023年7月に発生したものです。US-EAST-1でAmazon Kinesisの障害が発生し、その時間帯にそのリージョンでクラウドを使用していたほぼすべてのユーザーにとって厳しい一日となりました。サービスの劣化として、Kinesisで問題が発生しましたが、その詳細はオンラインで公開されているPost-mortemで確認できます。
この障害はAmazon ECSにどう関係したのでしょうか?具体的には、 Kinesisで発生した問題は設定の1つに起因していました。デプロイメント中にサービスでスパイクが発生し、Kinesisサービスに問題を引き起こしました。私たちには相互に依存関係のあるサービスがあります - CloudWatchはAmazon Kinesisに依存するサービスで、Amazon ECSのタスク開始時のログ記録はAmazon CloudWatchに依存しています。その結果、お客様がタスクを開始しようとしても、Kinesisの問題でCloudWatchが利用できなかったため、タスクを開始できませんでした。この経験から学んだことの1つが、Non-blocking I/O機能でした。これは、この特定の障害からの学びとして、そしてCOEプロセスとロードマップのAction Itemsの一部として導入され、お客様が特定のニーズに基づいて設定できるようになりました。マッピングとAction Itemsの一部により、そのような問題に対応するためのサービス要件に基づいて設定できるようになりました。
基盤となる依存関係に問題が発生した場合でも、私たちは様々な障害から継続的に学んでいます。私たちが言うように、Failureを受け入れています - 問題が発生することは好ましくありませんが、恐れることはなく、経験から学んでサービスを改善しています。
2つ目の例は、 2022年頃にAWS Fargateで発生した障害で、この特定の障害での作業により、AWSとAmazon ECSのロードマップに1年以上の影響を与えました。このケースでは、適切なリソース量にスケールされていないデータベースマイクロサービスがありました。同時に、多くのお客様が多数のECSタスクを起動したことで、私たちのマイクロサービスでエラーが発生し始め、カスケード障害を引き起こし、Amazon ECSサービスを使用するお客様にサービス中断が発生しました。
その理由は、Microserviceが単一のAvailability Zone内の独立したエンティティとしてではなく、すべてのAvailability Zoneにまたがって展開されていたためでした。そのため、特定のMicroservice内で依存関係のエラーが発生していました。この教訓から、私たちはサービスをできるだけ小さな展開単位で、各Availability Zone内の特定のCellに独立して展開するようになりました。これにより、このような問題が顧客に影響を与えることを防ぎ、効果的にテストができるようになりました。
また、私たちが学んだことの1つが、自動的なWeigh Awayと呼ばれる機能です。この学びに基づいて開発したこの機能により、特定のAvailability Zoneでの問題を識別できるようになりました。影響を受けているAvailability Zoneへの新しいタスクの起動からトラフィックを自動的にWeigh Awayすることで、Amazon ECSを使用するお客様のアカウント要件とサービスレベルを維持し続けることができます。これらの問題はロードマップに大きな影響を与え、新機能の開発の代わりに、お客様向けのAmazon ECSの可用性を向上させるための改善に注力することになりました。
ここで、これまでの内容を簡単に振り返ってみましょう。Amazon ECSで私たちがどのように可用性とレジリエンスのためにサービスを構築しているかについて説明しました。インフラストラクチャ、ソフトウェア、スケールという3つの異なる障害の次元と、Amazon ECSでこれらをどのように構築しているかについて議論しました。また、お客様がECSの構成要素、テナント、メカニズム、機能を使用して、私たちが構築した基盤となる機能をどのように活用できるかについても説明しました。継続的な改善について取り上げ、これを展開、運用実践、学習メカニズムにどのように活用して、Amazon ECSを定期的に改善し続けているかについても説明しました。
本日はre:Inventの最初のセッションでしたので、皆様のご参加に感謝申し上げます。素晴らしい1週間になることを願っています。他にもAmazon ECSのセッションが用意されています。新機能のリリースにより予定が変更される可能性がありますが、お手持ちの携帯電話でAWSイベントをチェックするか、外の掲示板で各セッションの場所をご確認ください。イベント期間中の他のAmazon ECSセッションにもぜひご参加ください。5日間で約30のセッションが用意されており、Amazon ECSについてさらに詳しく学ぶことができます。
このQRコードをスキャンすると、プレゼンテーション資料のコピーと、多数のリソースやリンクが掲載されているランディングページにアクセスできます。本日お話しした多くのトピックは、ホワイトペーパー、ブログ投稿、記事、ドキュメントとして提供されており、すべて1つのランディングページにまとめられています。録画も公開後にそこで視聴できるようになります。他のセッションの妨げにならないよう、ここでは質疑応答は行いませんが、私たちはホールの外でお待ちしています。お帰りの前に、お手持ちの携帯電話でイベントアプリを開き、アンケートにご回答いただければ幸いです。どのような点が役立ったか、改善のためのフィードバック、またはAmazon ECSサービスについてさらに学びたいトピックがあれば、ぜひお聞かせください。
※ こちらの記事は Amazon Bedrock を利用することで全て自動で作成しています。
※ 生成AI記事によるインターネット汚染の懸念を踏まえ、本記事ではセッション動画を情報量をほぼ変化させずに文字と画像に変換することで、できるだけオリジナルコンテンツそのものの価値を維持しつつ、多言語でのAccessibilityやGooglabilityを高められればと考えています。
Discussion