こんにちは、梅原です。re:Invent2024の参加からもう一ヶ月たったとは信じられません。
本記事は、re:Invent2024で参加した「Amazon ECS & AWS Fargateを使ったセキュアでパフォーマンスに優れたアプリケーションの構築」というChalk talkについてのセッションレポートです。

AWS Well-Architectedの4つの柱の観点を、ECS上のアプリケーションでどのように満たすかというセッション内容でした。
具体的にセキュリティ・信頼性・パフォーマンス効率・運用上の優秀性の4つの柱に絞って、以下内容について話がありました。
セキュリティの柱
- 環境変数を使った秘匿情報の受け渡し
- セキュアなAWSサービスへのアクセス
- ネットワークセキュリティを強化する方法
信頼性の柱
- どのようにして信頼性を高くするか
- AWS Fault Injection Serviceを使ったテスト
パフォーマンス効率の柱
- どのようにしてコンピュートリソースを調整するか
- ECSタスク内のコンテナ起動高速化
運用上の優秀性の柱
- オブザーバビリティの重要性
- 高速なデプロイの実現
本記事では、各柱から一つずつピックアップして内容を整理したいと思います。
- セキュリティの柱(環境変数を使ったセキュアな秘匿情報の受け渡し)
- 信頼性の柱(どのようにして信頼性を高くするか)
- パフォーマンス効率の柱(ECSタスクの起動高速化)
- 運用上の優秀性の柱(高速なデプロイの実現)
- 最後に
セキュリティの柱(環境変数を使ったセキュアな秘匿情報の受け渡し)
セキュリティの柱では環境変数の受け渡し方法について取り上げます。
DBに接続するためのエンドポイントやユーザ情報などの秘匿情報は、ソースコードにベタ書きしてしまうと漏洩のリスクがあります。AWS上でアプリケーションを構築するときは、AWS Systems Manager Parameter StoreやAWS Serects Managerなど、セキュアに秘匿情報に保管することが推奨されています。
ECSではタスク起動時に、Parameter Storeなどに保管している値を取得して、コンテナの環境変数として設定することができます。Parameter Storeなどから環境変数を設定することで、セキュアに秘匿情報の受け渡しを実現することができます。
設定方法はタスク定義書にParameter StoreのARNを指定するだけです。 タスク自体がParameter Storeなどに取得するのではなく、あくまでもコンテナを起動するタイミングで環境変数が設定されるので、Parameter Storeなどの取得権限が必要なのはタスク実行ロールになります。

信頼性の柱(どのようにして信頼性を高くするか)
続いて信頼性の柱からは、どのようにして信頼性を高くするかについてです。
AWSなどのクラウドサービスを使う上での原則的な話にはなりますが、「design for failure」を意識して設計する事が必要です。
障害を見越して設計することで、障害が起こってしまっても完全にサービスが落ちることを少なくしたり、元の状態へ自動復旧することができます。
例えば、タスクを複数AZにまたがって起動することで、一つのAZに障害が起こってもサービスを継続して提供することができます。
他にも、指定したタスク数を維持してくれるオートヒーリング機能はAWS実行基盤側の障害対策になります。
re:Invent直前のアップデートで、ECSタスクのマルチAZリバランス機能が追加されました。 これまではタスクがマルチAZで均等に分散されるのはベストエフォートでした。 今回のアップデートからは、ECS側で定期的に不均等になっていないか確認し、不均等になっていればタスクの入れ替えを実施してくれます。

パフォーマンス効率の柱(ECSタスクの起動高速化)
パフォーマンス効率の柱の部分では、ECSタスクの起動高速化の話がありました。
AutoScalingを設定しているECSサービスでは、リクエスト数やCPU使用率によってタスク数が変動し、新しいタスクが起動します。
すぐにリクエストを処理したい場合は、できるだけ高速にコンテナを起動する必要があります。
タスクの起動高速化の方法は2点あります。
コンテナイメージの最小化
コンテナを使う上での原則ですが、コンテナイメージのサイズはできるだけ最小化しましょう。
通常コンテナの起動はコンテナイメージをすべてダウンロードしてからなので、コンテナイメージを最小化することでダウンロード時間の短縮に繋がります。 コンテナイメージに不要なパッケージは入れ込まないことであったりマルチステージビルドの活用、サイズが大きいファイルや静的コンテンツはS3やEFSに外出しするなどが効果的です。SOCIを使った遅延読み込み
Seekable OCIを使ってコンテナイメージの遅延読み込みを使うことでも起動を高速化することができます。
SOCIを使うことでコンテナイメージ全体のダウンロードを待たずに、先にコンテナを起動する事ができ、起動に必要がない残りのファイルは起動と並行してダウンロードすることができます。 コンテナイメージのダウンロードが完了するまで待つ必要がないので、起動を高速化することができます。 aws.amazon.com
運用上の優秀性の柱(高速なデプロイの実現)
最後に運用上の優秀性の柱からは、高速なデプロイを実現する方法を紹介します。
ELBに紐づいているECSサービスでは、タスク起動時にLBのヘルスチェックが成功してからリクエストの処理が開始されます。
タスク終了時もコネクションドレインニングの機能で、コネクションがなくなってからタスクが終了されます。
これらはデフォルトの設定値だと安全な起動・終了が意識されているため、必要以上にデプロイに時間を要してしまいます。
以下の設定値を下げることで、ELBからのヘルスチェックが合格するまでの時間を短縮することができます。
HealthCheckIntervalSeconds
HealthyThresholdCount
またコネクションドレインニングの間隔を下げることで、タスクが完全に停止するまでの時間を早めることができます。
- deregistration_delay.timeout_seconds
最後に
本セッションで紹介された個々のプラクティスはどれも具体的ですぐにでも実践できる内容でした。 ECSを使う上でのエッセンスが詰まった内容だったので非常に参考になりました。
Well-Architected Frameworkには、コンテナに特化したLensもあるので気になる方は参考にしてみてください。