ECSの「Capacity is unavailable」エラーに興味をもった。

ECSで運用しているコンテナで最近503エラーがブラウザ上で表示されることが多々ありました。ですので改めてエラーの原因と対策に関して考えてみました。

😱 突然のエラー発生、その時あなたは?

深夜、突然のアラート。「サービスが応答しない」との報告。コンソールにアクセスすると、見慣れないエラーメッセージが目に入ります。

service single-product was unable to place a task. Reason: Capacity is unavailable at this time. Please try again later or in a different availability zone.

本記事では、このエラーの背景と対策をわかりやすく解説します。

🔍 エラーの技術的背景を理解する

なぜリソースは「不足」するのか?

ECSでは、各タスクのリソース(CPU、メモリ)を事前に設定します。例えば:

{
    "cpu": "256",
    "memory": "512",
    "essential": true,
    "image": "nginx:latest"
}

この設定に基づき、以下の状況でリソースが不足します:

  1. クラスタ内の利用可能リソースが不足

  2. 特定のアベイラビリティゾーンでリソースが枯渇

  3. EC2インスタンスのキャパシティが限界に達している

影響度

重要度: 🔥🔥🔥(非常に高い)

  • 新規タスクが起動できない

  • オートスケーリングが動作しない

  • サービスの可用性が著しく低下

🚑 緊急対応フロー(30分以内の解決を目指して)

Step 1: 状況把握(5分)

# クラスタの状態を確認
aws ecs describe-clusters --clusters your-cluster-name

📋 出力例:

{
  "clusters": [{
    "clusterName": "production-cluster",
    "runningTasksCount": 50,
    "pendingTasksCount": 10,
    "registeredContainerInstancesCount": 5,
    "statistics": [{
      "name": "CPU",
      "value": "75%"
    }]
  }]
}

チェックポイント:

  • pendingTasksCount > 0 の場合:リソース不足でタスク配置が失敗中

  • statistics.CPU > 70% の場合:リソース枯渇のリスク

Step 2: 即時対応(10分)

Fargateの場合:

# 現在のタスク定義を確認
aws ecs describe-task-definition --task-definition your-task

# 新しいリソース割り当てのタスク定義を登録
aws ecs register-task-definition --cli-input-json file://new-task-def.json

📋 タスク定義の修正例(new-task-def.json):

{
  "family": "web-app",
  "containerDefinitions": [{
    "name": "web",
    "image": "nginx:latest",
    "cpu": 512,  // 元々の256から増加
    "memory": 1024  // 元々の512から増加
  }]
}

EC2の場合:

# 現在のインスタンス状態を確認
aws ecs list-container-instances --cluster your-cluster

# 新しいインスタンスを追加
aws autoscaling set-desired-capacity \
  --auto-scaling-group-name your-asg \
  --desired-capacity 5  # 現在の値よりも+2追加など

Step 3: 恒久対策(15分)

Auto Scaling設定の最適化

aws application-autoscaling put-scaling-policy \
  --policy-name cpu-tracking \
  --service-namespace ecs \
  --resource-id service/your-cluster/your-service \
  --scalable-dimension ecs:service:DesiredCount \
  --policy-type TargetTrackingScaling \
  --target-tracking-scaling-policy-configuration '{
    "TargetValue": 70.0,
    "PredefinedMetricSpecification": {
        "PredefinedMetricType": "ECSServiceAverageCPUUtilization"
    },
    "ScaleOutCooldown": 60,
    "ScaleInCooldown": 60
  }'

重要な設定値:

  • TargetValue: 70%(適度な余裕を持つ)

  • ScaleOutCooldown: 60秒(急激なスケールアウトを防ぐ)

🛡️ 予防措置:99.9%の可用性を実現する

1. プロアクティブなモニタリング

CloudWatchアラームの設定例:

aws cloudwatch put-metric-alarm \
  --alarm-name ECS-CPU-Alert \
  --metric-name CPUUtilization \
  --namespace AWS/ECS \
  --statistic Average \
  --period 300 \
  --threshold 70 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 2

2. リソース管理の最適化

# 必要なタスク数の計算例
peak_load = 5000  # req/min
safety_margin = 1.3  # 30%の余裕を見積もる
required_tasks = (peak_load / 1000) * safety_margin  # 6.5 ≈ 7タスク必要

まとめ:安定運用への道筋

  1. モニタリングの徹底

    • CPU使用率 > 70%でアラート発報

    • メモリ使用率 > 65%で警告

    • pending_tasks > 0の監視を常時行う

  2. スケーリング戦略

    • ピーク時の30%増しでキャパシティを確保

    • 複数のアベイラビリティゾーンを利用

    • プリエンプティブなスケーリングを実施

  3. 運用体制の整備

    • 明確なインシデント対応フローの策定

    • 定期的な負荷テストの実施

    • ドキュメントの整備・更新


※より詳細な情報はAWS公式ドキュメントをご確認ください。

いいなと思ったら応援しよう!

この記事が参加している募集