🚚

ECSのApplication Auto Scalingまとめ

2024/06/24に公開

はじめに

本番環境にて、ECSのオートスケール設定が適切でなかったために、スパイクアクセスに耐えられずサイトがダウンするというやらかしをしました。
自戒を込めて記事にまとめます。

前提

  • ECS on Fargate
  • Terraform

Application Auto Scaling

ECS on Fargateで利用可能なApplication Auto Scalingでは、CloudWatchアラームで定めたメトリクスの閾値で、スケールアウトやスケールインを実行します。

1. ステップスケーリングポリシー

ステップスケーリングポリシーは、段階的にスケールアクションを設定できるポリシーです。

resource "aws_appautoscaling_target" "ecs_target" {
  max_capacity       = 3
  min_capacity       = 1
  resource_id        = "service/clusterName/serviceName"
  scalable_dimension = "ecs:service:DesiredCount"
  service_namespace  = "ecs"
}

resource "aws_appautoscaling_policy" "ecs_step_policy" {
  name               = "cpu-step-autoscaling"
  service_namespace  = aws_appautoscaling_target.ecs_target.service_namespace
  scalable_dimension = aws_appautoscaling_target.ecs_target.scalable_dimension
  resource_id        = aws_appautoscaling_target.ecs_target.resource_id
  policy_type        = "StepScaling"

  step_scaling_policy_configuration {
    adjustment_type         = "ChangeInCapacity"
    cooldown                = 90
    metric_aggregation_type = "Average"

    # CPUの平均使用率が70%-85%の場合コンテナを3増やす
    step_adjustment {
      metric_interval_lower_bound = 0
      metric_interval_upper_bound = 15
      scaling_adjustment          = 3
    }

    # CPUの平均使用率が85%以上の場合コンテナを6増やす
    step_adjustment {
      metric_interval_lower_bound = 15
      scaling_adjustment          = 6
    }
  }
}

resource "aws_cloudwatch_metric_alarm" "cpu_scale_out_alarm" {
  alarm_name          = "${var.ecs_service_name}-cpu-scale-out"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 1
  metric_name         = "CPUUtilization"
  namespace           = "AWS/ECS"
  period              = 60
  statistic           = "Average"

  // Step ScalingのCPU使用率の閾値の基準を平均70%とする
  threshold = 70
  dimensions = {
    ClusterName = var.ecs_cluster_name
    ServiceName = var.ecs_service_name
  }
  alarm_actions = [aws_appautoscaling_policy.ecs_step_policy.arn]
}

※設定されている値は適当です。

2. ターゲット追跡スケーリングポリシー

ターゲット追跡スケーリングポリシーは、CloudWatchアラームのメトリクスのターゲット値を維持するようにスケールアウトやスケールインが制御されるポリシーです。
ステップスケーリングポリシーと異なり、増減させるタスク数の設定は不要になります。
メトリクスがターゲット値を超えている場合のみスケールアウトします。

resource "aws_appautoscaling_target" "ecs_target" {
  max_capacity       = 3
  min_capacity       = 1
  resource_id        = "service/clusterName/serviceName"
  scalable_dimension = "ecs:service:DesiredCount"
  service_namespace  = "ecs"
}

resource "aws_appautoscaling_policy" "ecs_target_policy" {
  name               = "cpu-target-autoscaling"
  service_namespace  = aws_appautoscaling_target.ecs_target.service_namespace
  scalable_dimension = aws_appautoscaling_target.ecs_target.scalable_dimension
  resource_id        = aws_appautoscaling_target.ecs_target.resource_id
  policy_type        = "TargetTrackingScaling"
  target_tracking_scaling_policy_configuration {
        # 維持するターゲット値
    # CPUの平均使用率が50%になるように維持する
        predefined_metric_specification {
      predefined_metric_type = "ECSServiceAverageCPUUtilization"
    }
    target_value = 50
    # スケールインの間隔を180秒空ける
    scale_in_cooldown = 180
    # スケールアウトの間隔を90秒空ける
    scale_out_cooldown = 90
  }
}

※設定されている値は適当です。

負荷テスト

リリース前に検証環境等で負荷テストを実施して、オートスケールが想定通り動くか確認しましょう。
私の場合は、リリース前に行っていなかったため、テストの段階で気づけたはずのバグに気づかぬままリリースしてしまいサイトをダウンさせました...

パフォーマンス要件を確認する

秒間の最大アクセス数などを確認することで、負荷テストの基準が決まり、テストを実行できるようになります。

テストの実施

負荷テストには以下二つのツールを使用しました。
手軽に使えるのはabコマンドです。
設定をいろいろカスタムしたい場合はLocustがおすすめです。

以下の記事を参考にすると、テストを何回か実行して細かな調整が必要だということが分かります。
設定して終わりではなく、テストを必ず実行しましょう。
https://docs.aws.amazon.com/AmazonECS/latest/bestpracticesguide/capacity-autoscaling.html

私の場合も何度かテストを実施して、設定をチューニングしました。

また、テストを実施する際は下記の観点をチェックすることをおすすめします。

  1. 期待する一連のCloudWatchメトリクスが取得できているか
  2. Auto Scalingのスケールアウトおよびスケールインは設定されているか
  3. アプリケーションからエラーが出力されていないか
  4. ログ出力の内容は適切か(欠損等はしていないか、ログレベルは妥当か)

参考文献: AWSコンテナ設計・構築[本格]入門
https://amzn.asia/d/gxJwlqJ

最後に

この記事で伝えたかったことは下記2点です。

  1. リリース前に必ず負荷テストを実施しましょう。
  2. オートスケール設定は、設定して終わりではなくチューニングが必要です。

参考URL

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/appautoscaling_policy.html

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm

https://docs.aws.amazon.com/autoscaling/application/userguide/step-scaling-policy-overview.html

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/service-autoscaling-targettracking.html

ENECHANGE

Discussion