🔍

【Terraform】CloudWatchによるECSスロットリング監視: 効果的なメトリクスの選定と活用法

2024/04/22に公開

はじめに

この記事は以前の投稿と関連しています。
もしまだ読まれていない場合は、ぜひ先に以下の内容をお読みください。

https://zenn.dev/take_tech/articles/4f728035d166b1

ECSタスクのライフサイクルの理解 🔄

ECSにおいてタスクは複数のライフサイクルステータスを持ちます。主にProvisioning、Pending、Activating、Running、Deactivating、Stopping、そしてStoppedの状態を経て遷移します

  • Provisioning: タスクがリソースを確保している初期段階です。
  • Pending: タスクが開始される準備が整い、リソースが割り当てられるところです。
  • Activating: タスクがアクティブな状態へ移行する過程です。
  • Running: タスクが正常に実行されている状態です。
  • Deactivating: タスクが非アクティブな状態へ移行する過程です。
  • Stopping: タスクの停止プロセスが始まったことを示します。
  • Stopped: タスクが完全に停止し、リソースが解放された状態です。

タスクがRunning状態に移行しない場合、それは通常リソースの制約(例えばCPUやメモリ不足)や設定ミス、ネットワークの問題などが原因であると考えられます。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-lifecycle-explanation.html

ECSスロットリングの理解 🎰

スロットリングとは、コンテナ化されたアプリケーションを実行しているタスクが、リソース制限(CPUやメモリなど)により十分なリソースを確保できず、適切に実行されない状態と認識しています。これは、タスクが「Running」状態に達する前に、リソースの割り当てが制限されるか、コードにバグが含まれておりコンテナの立ち上げに失敗するため、「Pending」状態に留まるか、実行を試みるもののうまく立ち上がらずに「Stopped」状態に遷移することがあります。

厳密には、スロットリングが発生すると、ECR(Elastic Container Registry)からコンテナイメージを繰り返しPullする行動が起こることがあります。これは、タスクが適切に起動できずに再試行される場合によく見られます。コンテナイメージのサイズが大きい場合、その都度のダウンロードでネットワークのリソースを消費し、転送データ量に基づいた料金がAWSに課金されるため、コストが増大します。ここで重要なのは、スロットリング自体が直接的にECSの料金を増やすわけではなく、このネットワークトラフィックの増加がコストアップに繋がります

https://speakerdeck.com/msato/amazon-ecsfalsenetutowakuguan-lian-kosutofalsehua?slide=7

(Terrafrom)CloudWatchによるアラーム設定⏰

CloudWatchを使用してECSのタスクのステータスに関するメトリックを監視することで、問題が発生した際に迅速に対応することが可能です。具体的には、以下のスクリプトを使用してPendingTaskCountメトリクスに基づいたアラームを設定します。

コードは一部省略 or 改変しています

resource "aws_cloudwatch_metric_alarm" "ecs_throttling_alarm" {
  alarm_name          = "ecs-throttling-alarm-staging"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 2
  metric_name         = "PendingTaskCount"
  namespace           = "AWS/ECS"
  period              = 60  # 1分ごとに監視
  statistic           = "Average"
  threshold           = 5   # 5タスク以上がPending状態ならアラーム
  alarm_description   = "コードのバグによるコンテナの起動失敗が原因で、ECSのPendingTaskCountが設定された閾値を超えた場合にアラームが発生"
  actions_enabled     = true
}

この設定により、指定した閾値以上のタスクがPending状態にある場合にアラームが発生し、運用チームに通知されます。

なぜRunningTaskCountではなくPendingTaskCountを監視するのか (本記事の要点⭕️)

一般的に、スロットリングの問題を特定するためには、CPUUtilizationやMemoryUtilizationといったリソースの使用量を表すメトリクスを同時に監視することが有効です。

タスクの状態の区別がつかない問題: RunningTaskCountを監視している場合、タスクが正常に起動してRunning状態にあるかどうかを監視することはできます。しかし、スロットリングによる影響でタスクが短時間に何度も停止と再起動を繰り返している場合、一瞬Running状態になるものの、それが持続的な健全な状態であるとは限りません。つまり、タスクがRunning状態になったからといって、すべてが正常であるとは断定できないためです

一方で、PendingTaskCountが異常に高い値を示している場合、多くのタスクが起動のためのリソースを待っている状態であることを意味しますが、実際にはタスクが適切にリソースを割り当てられずに待機している可能性があります。いわゆる無限ループ状態です。そのため、このPending状態の回数が異常な際には、ECSが起動を試みているものの上手く立ち上がらない状態である可能性が高いです。したがって、一定間隔でPendingTaskCountを監視することで、ECSのスロットリングに適切に気づくことができるのではないかということが考えられます。

補足

一概にどのメトリクスが適切かは状況により異なります。一般的にリソースの制限によるスロットリングの場合、CPUやメモリの利用量を表す「CPUUtilization」や「MemoryUtilization」の監視が有効です。これにより、リソースが逼迫している状態を正確に把握することができます。

一方で、コードにバグがあるなどの技術的な問題でコンテナの起動に失敗し、タスクが「Pending」状態に留まる場合は、「PendingTaskCount」の監視が推奨されます。このメトリクスは、タスクがリソース割り当てを待っているが、実際には起動できずに待機していることを示すため、スロットリングの診断に役立ちます。これらのメトリクスはあくまで参考の一つとして活用し、状況に応じて適切な監視ポリシーを定めることが重要です。

まとめ

ECSのスロットリング対策には、「CPUUtilization」や「MemoryUtilization」など、リソース使用量を示すメトリクスの監視が推奨されます。しかし、技術的な問題でコンテナの起動が遅れ、「Pending」状態が続く場合は、「PendingTaskCount」の監視が重要です。これにより、リソースの問題だけでなく、コードの問題も効果的に特定できます。

参考

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-lifecycle-explanation.html

https://speakerdeck.com/msato/amazon-ecsfalsenetutowakuguan-lian-kosutofalsehua?slide=7

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm

最後に

noteでも記事を執筆していますので、ぜひチェックしてみてください。

https://note.com/take_lifelog/n/n7acc1450679e

Discussion