はじめに
ECS+Fargate の AutoScaling は便利で、徐々にアクセス量が増えていくようなケースには対応できるものの、一気にトラフィックが3倍になるようなバーストケースは、仮に予見されるものであってもCPUリソースやアクセス量を監視しているだけでは対応しきれない。
そういったケースでは、予めスケジュールを組んでタスク量を調節しておくことで対応をしよう。
※予見できないバーストトラフィックはさすがに無理なので、そこはもうある程度余裕をもってリソースを用意しておくしかないだろう。
本記事では、ベースに前回の記事の予備知識があることを前提とする。ECS+Fargate や AutoScaling に関する基本的な設定は改めて説明はしないので悪しからず。
また、クラスメソッド先生の記事も参考に。
なお、EC2のスケジュールベースの AutoScaling はマネージメントコンソールで確認できるが、ECS+Fargateの場合はどこを見ても確認できない。謎だが、ちゃんと動作はするので気にしないことにした。
スケジュールベースの AutoScaling の Terraform での設定方法
Terraform では appautoscaling_scheduled_action
のリソースを使う。
対して難しいことはない。上記の例のように、時間帯でトラフィックが予期できる場合は、以下のように2つのスケジュールを組むことでリソース量をコントロール可能になる。
resource "aws_appautoscaling_scheduled_action" "ecsfargate_peak" {
name = "ecsfargate_peak"
service_namespace = aws_appautoscaling_target.ecsfargate.service_namespace
resource_id = aws_appautoscaling_target.ecsfargate.resource_id
scalable_dimension = aws_appautoscaling_target.ecsfargate.scalable_dimension
schedule = "cron(15 * * * ? *)"
scalable_target_action {
min_capacity = 20
max_capacity = 40
}
}
resource "aws_appautoscaling_scheduled_action" "ecsfargate_normal" {
name = "ecsfargate_normal"
service_namespace = aws_appautoscaling_target.ecsfargate.service_namespace
resource_id = aws_appautoscaling_target.ecsfargate.resource_id
scalable_dimension = aws_appautoscaling_target.ecsfargate.scalable_dimension
schedule = "cron(20 * * * ? *)"
scalable_target_action {
min_capacity = 10
max_capacity = 20
}
}
schedule
のプロパティは、ユーザーガイドに設定例が書かれている。at
で日時指定、rate
で間隔で定期的に動作させることができ、cron
で毎時何分に起動や、毎日何時何分に起動といったことができる。cron
は CloudWatch
Event の記載方法に従う。
上記の例では、毎時15分にピークトラフィックに備えてスケールアウトさせ、毎時20分に収まるのでスケールインする。当然ながらこれは例であって、ECS+Fargate は課金単位が1時間なので、こういった設定をする意味はない。
実際に動作させる
上記の Terraform を apply した後の動作がこちら。
多少のタイムラグはあるものの、16:16 に必要なタスク数が上がってタスク実行され、16:21 には下がって drain されている。
ECSのサービスのログでも、以下のように出力されていて、時間通りにスケジュールでタスク数の最大と最少が変更されていることが分かる。
今回はCPU使用率によるスケールインのポリシーも設定しているため、スケジュールで MAX:4/MIN:2 になった後に、CPU使用率が低いためにタスク数が2まで推移する、といった動作だ。
これで、CPU使用率やトラフィック量だけでなく、時間でより細かくタスク数をコントロールできるようになった!