ECS サービスでスケールインから特定タスクを除外する方法を教えてください
困っていた内容
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": []
}
参考資料
- Amazon ECS タスクがスケールインイベントによって終了するのを防ぐ - Amazon Elastic Container Service
- Amazon ECS タスクのスケールイン保護の発表 | Amazon Web Services ブログ
- ECS Exec を使用して Amazon ECS コンテナをモニタリングする - Amazon Elastic Container Service
- update-task-protection — AWS CLI 2.24.25 Command Reference
- get-task-protection — AWS CLI 2.24.25 Command Reference
- Amazon ECS サービス - Amazon Elastic Container Service
Fargate でタスクを実行するサービスについては、サービススケジューラは、新しいタスクの起動時や実行中タスクの停止時に、アベイラビリティーゾーン間の負荷バランスを維持するよう最大限試みます。タスク置き換え戦略や制約を指定する必要はありません。