ECS Fargateのタスク起動時のライフサイクル

2021/09/18に公開

ECSに乗せているアプリケーションの起動は早いはずなのにECSのタスクの起動が遅いなと感じたため、タスクが起動してからRUNNINGになるまでの経緯を1秒ごとにaws ecs list-tasksコマンドを出力し追ってみました。

#!/bin/zsh

index=1

while true; do
  tasks=$(aws ecs list-tasks --cluster cluster-name --service service-name | jq -r  '.taskArns | join(",") ')
  tasks=("${(@s/,/)tasks}")

  echo $tasks
  for task in $tasks; do
    taskname=$(echo $task | sed -e 's/.*\///g')
    aws ecs describe-tasks --cluster cluster-name --tasks $task > $taskname-$index.txt
  done
  index=$((index+1))
  sleep 1
done

なお、こちらが公式ドキュメント です。

"version": 1 -> 2, "status": "PROVISIONING" -> "PENDING"

PROVISIONING
Amazon ECS has to perform additional steps before the task is launched. For example, for tasks that use the awsvpc network mode, the elastic network interface needs to be provisioned.

NetworkInterfaceが作成されコンテナに割り当てられています。
version1から2は約10秒。


"version": 2 -> 3, "status" : "PENDING" -> "ACTIVATING"

PENDING
This is a transition state where Amazon ECS is waiting on the container agent to take further action.

ECRからコンテナイメージをpullしてます。
version2から3は約40秒。


"version": 3 -> 4, "status" : "ACTIVATING" -> "RUNNING"

ACTIVATING
Amazon ECS has to perform additional steps after the task is launched but before the task can transition to the RUNNING state. For example, for tasks that have service discovery configured, the service discovery resources must be created. For tasks that are part of a service that is configured to use multiple Elastic Load Balancing target groups, the target group registration occurs during this state.

このクラスターに対してAWS CloudMapで名前空間を作る設定をしているので、それ関連のリソースを作成しているようです。
version3から4は約30秒。

各種完了時間

aws ecs list-tasksの各種時間

イベント 時間
"createdAt" 2021-09-18T14:55:23.095000+09:00
"connectivityAt" 2021-09-18T14:55:27.021000+09:00
"pullStartedAt" 2021-09-18T14:55:36.180000+09:00
"pullStoppedAt" 2021-09-18T14:56:05.893000+09:00
"startedAt" 2021-09-18T14:56:36.997000+09:00

ELBの最初のヘルスチェックの時間 (@アクセスログ)

イベント 時間
/health-check 2021-09-18T05:56:55+00:00

ECSコンソールのイベントタブ

イベント 時間
has started 1 tasks 2021-09-18 14:55:23 +0900
registered 1 targets in target-group 2021-09-18 14:56:40 +0900
updated state to STEADY_STATE 2021-09-18 14:56:59 +0900
service *** has reached a steady state 2021-09-18 14:56:59 +0900

タスク起動速度の改善で試したこと

改善方法はこちらのBlogに色々と紹介されています。
Speeding up Amazon ECS container deployments

ELBのヘルスチェックのIntervalとHealthy thresholdを短くしてみる

こちらは長くしても短くしても効果がありませんでした。
動きをみると上記設定に関わらず、コンテナの起動後にヘルスチェックが実行されて、1回でhealthyになっているように見受けられました。

ECSのヘルスチェックの猶予期間を短くしてみる

こちらも長くしても短くしても変化がありませんでした。

コンテナイメージをキャッシュする

これは間違いなく効果があるはず!と思いましたがFargateは未対応のようです...
Issueは上がっているようなので待つしかないですね。
[Fargate/ECS] [Image caching]: provide image caching for Fargate.

結局は、簡単には起動速度を早くすることはできなそう。
もともとアクセススパイクに対して迅速にスケールさせるために調べ始めたのですが、スケーリングポリシーを見直したり、異常の検知をCloudWatchではなく自前でやったり、サーバーの負荷が急上昇しないようにプログラム自体を改善したり、CDNをサーバーの前に置いたりするほうが良さそうです。

Discussion