ECS サービスでスケールインから特定タスクを除外する方法を教えてください

ECS サービスでスケールインから特定タスクを除外する方法を教えてください

Clock Icon2025.03.18

困っていた内容

ECS サービスで複数の Fargate タスクを実行しています。
スケールインの際、処理が行われているタスクは停止対象にならないようにしたいです。
スケールイン対象選定の制御はできない認識ですが、何か方法はありませんか。

どう対応すればいいの?

ECS タスクのスケールイン保護を設定してください。

Amazon ECS タスクがスケールインイベントによって終了するのを防ぐ - Amazon Elastic Container Service

Amazon ECS タスクスケールイン保護を使用すると、サービスの自動スケーリングまたはデプロイからのスケールインイベントによってタスクが終了されるのを防ぐことができます。

スケールイン保護が有効に設定されているタスクは、スケールインの際も停止されません。

そのため、停止して欲しくないタスクのスケールイン保護を有効にすることで、スケールインからタスクを保護することが可能です。

スケールイン保護を有効にする方法は二つあり、状況に応じて選択してください。

  • コンテナ内からスケールイン保護エンドポイントに PUT リクエストを送る
  • AWS CLI 等で UpdateTaskProtection API を実行する

なお、スケールイン保護は、明示的に解除するか、時間経過(デフォルト:2時間、カスタマイズ可能)で自動解除されます。

また、スケールイン保護によりタスクが停止できない場合は、次のような ECS サービスイベントが記録されます。

イベント例
service hato-ECS-Service was unable to reach steady state because taskSet ecs-svc/123456789 was unable to scale in due to (reason 1 tasks under protection)

やってみた

スケールイン保護エンドポイントを利用

Amazon ECS Exec で対象のコンテナに接続して次のようなコマンドを実行します。

有効無効のコマンド例
# スケールイン保護を有効にする
curl --request PUT --header 'Content-Type: application/json' ${ECS_AGENT_URI}/task-protection/v1/state --data '{"ProtectionEnabled":true}'

# スケールイン保護を無効にする
curl --request PUT --header 'Content-Type: application/json' ${ECS_AGENT_URI}/task-protection/v1/state --data '{"ProtectionEnabled":false}'
確認のコマンド例
# スケールイン保護の状況を確認する
curl --request GET ${ECS_AGENT_URI}/task-protection/v1/state

# 有効時の実行結果例
curl --request GET ${ECS_AGENT_URI}/task-protection/v1/state
{
  "protection": {
    "ExpirationDate": "2025-03-01T05:11:30Z",
    "ProtectionEnabled": true,
    "TaskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/abcdef41fd7f44f39b5db50f5f1d6326"
  }
}

# 無効時の実行結果例
curl --request GET ${ECS_AGENT_URI}/task-protection/v1/state
{
  "protection": {
    "ExpirationDate": null,
    "ProtectionEnabled": false,
    "TaskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/abcdef41fd7f44f39b5db50f5f1d6326"
  }
}

UpdateTaskProtection API を利用

AWS CLI の update-task-protectionコマンドを実行して有効/無効を設定します。

有効無効のコマンド例
# スケールイン保護を有効にする
aws ecs update-task-protection \
    --cluster 【ECS クラスター名】 \
    --tasks 【タスク ID】 \
    --protection-enabled

# スケールイン保護を無効にする
aws ecs update-task-protection \
    --cluster 【ECS クラスター名】 \
    --tasks 【タスク ID】 \
    --no-protection-enabled

スケールイン保護の状況を確認する場合はAWS CLI の get-task-protectionコマンドから確認できます。

確認のコマンド例
# スケールイン保護の状況を確認する
aws ecs get-task-protection \
    --cluster 【ECS クラスター名】 \
    --tasks 【タスク ID】

# 有効時の実行結果例
aws ecs get-task-protection \
    --cluster hato-ecs-cluster \
    --tasks abcdef41fd7f44f39b5db50f5f1d6326
{
    "protectedTasks": [
        {
            "taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/abcdef41fd7f44f39b5db50f5f1d6326",
            "protectionEnabled": true,
            "expirationDate": "2025-03-01T15:11:11+09:00"
        }
    ],
    "failures": []
}

# 無効時の実行結果例
aws ecs get-task-protection \
    --cluster hato-ecs-cluster \
    --tasks abcdef41fd7f44f39b5db50f5f1d6326
{
    "protectedTasks": [
        {
            "taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/abcdef41fd7f44f39b5db50f5f1d6326",
            "protectionEnabled": false
        }
    ],
    "failures": []
}

参考資料

Fargate でタスクを実行するサービスについては、サービススケジューラは、新しいタスクの起動時や実行中タスクの停止時に、アベイラビリティーゾーン間の負荷バランスを維持するよう最大限試みます。タスク置き換え戦略や制約を指定する必要はありません。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.