0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ECS on Fargateで構築したWEBアプリの環境に、Terraformを使用してAuto Scalingの機能を導入する

Last updated at Posted at 2024-10-13

概要

表題の通り、Terraformを用いて自動スケーリング機能を追加しました。本記事では、その具体的な実装方法について記述します。

Auto Scalingの種類

  • Auto Scalingは、主に3種類の設定項目がある為、各機能について説明する

ターゲット追跡ポリシ

  • システムのパフォーマンスを安定させる為に、CPU使用率を目標値に保つ様、コンテナ数を自動的に調整する
  • 指定したメトリクス(例:CPU使用率、メモリ使用量)が設定した目標値を超えるか下回った際、自動的にスケールイン(リソースを減らす)またはスケールアウト(リソースを増やす)を行う
  • AWSが提供するマネージドサービスであり、導入が比較的容易
  • AWSが推奨するスケーリング方法

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

  • リソースの使用率の変化に対してより細かく閾値を決めてスケールイン、アウトを行う
  • CloudWatchアラームをトリガーとして、CPU使用率が特定の閾値を超過するか、閾値未満になるとアラームが発生し、それに応じたスケーリングアクションが実行される
  • スケールアウトはリソースを追加するだけなので比較的容易に設定出来るが、スケールインはリソース削減に伴うパフォーマンス低下やコスト増加のリスクがある為、設定が複雑になる
  • 閾値を適切に設定をする必要がある為、導入が難しいが、詳細にスケーリングを調整したい場合に便利

スケジュールに基づくスケーリング

  • 指定した日時に基づいて、タスク数を増減させる
  • 他のスケーリングポリシと組み合わせて利用可能

参考資料

構築手法

  • 下記の構築内容は、ターゲット追跡ポリシ、スケーリングポリシのどちらでも使用する
resource "aws_appautoscaling_target" "auto_scale_target" {
  service_namespace  = "ecs" # 固定値
  resource_id        = "service/サービス名/クラスター名"
  scalable_dimension = "ecs:service:DesiredCount" # 固定値
  min_capacity       = # 最小のタスク数
  max_capacity       = # 最大のタスク数
}

参考資料

Terraform

構築時の参考資料

ターゲット追跡ポリシの構築

resource "aws_appautoscaling_policy" "scale_up_policy" {
  name               = "任意の名前"
  policy_type        = "TargetTrackingScaling"
  service_namespace  = "ecs"
  resource_id        = "service/クラスタ名/サービス名"
  scalable_dimension = "ecs:service:DesiredCount"
  
  # policy_typeがTargetTrackingScalingの為、target_tracking_scaling_policy_configurationを使用して設定する
  target_tracking_scaling_policy_configuration {
    predefined_metric_specification {
      # ECSサービスの平均CPU使用率をターゲットメトリクスとして指定
      predefined_metric_type = "ECSServiceAverageCPUUtilization"
    }    
    # スケールイン(リソースの減少)を無効にするかどうかを指定する。スケールインは必要な為、false に設定
    disable_scale_in   = false
    # 目標CPU使用率のパーセンテージ
    target_value       = 50
    # スケールインが完了してから次のスケールインが開始出来るまでの時間(秒)を指定
    scale_in_cooldown  = 300
    # スケールアウト(リソースの増加)が完了してから次のスケールアウトが開始出来るまでの時間(秒)を指定
    scale_out_cooldown = 300
  }
  
  depends_on = [aws_appautoscaling_target.auto_scale_target]
}
メソッド 説明
policy_type ターゲット追跡ポリシーで構築する為、TargetTrackingScalingを選択。これにより、特定のメトリクス(CPU使用率やメモリ使用率など)に基づいて、リソースの自動スケーリングが実行される
service_namespace どのAWSリソースに対して、Auto Scalingを適用するか指定する。今回は、ECSのサービスに対して適用する為、namespaceにはecsを指定
scalable_dimension ECSサービスのタスク数をスケーリングする為のAWS Auto Scalingの設定。この設定は、「タスク数」を指定するのではなく、スケーリングするリソース(ここではタスク数)の「スケーリング可能な属性」を指定する
resource_id Auto Scalingを追加する為、ECSのサービスを指定する。リソースIDの形式は、service/クラスタ名/サービス名
predefined_metric_type AWS Auto Scalingでサポートされているサービスに対して適用する。今回は、ECSサービスの平均CPU使用率をターゲットメトリクスとして指定
depends_on aws_appautoscaling_targetが作成された後にスケーリングポリシーが適用される様に、明示的に依存関係を設定する為に使用。依存関係を管理する事で、リソースの作成順序が保証される

参考資料

Terraform

構築時の参考資料

スケーリングポリシの構築

  • Terraformの公式から提供されている構築例をもとに、AWS ECSサービスの自動スケーリングを設定
  • 実際の設定については、以下のGitHubリポジトリのモジュールを活用
  • [GitHub] AWS ECS Service Autoscaling Module

CloudWatch Alarmの設定内容

#------------------------------------------------------------------------------
# AWS Auto Scaling - CloudWatch Alarm CPU High
#------------------------------------------------------------------------------
resource "aws_cloudwatch_metric_alarm" "cpu_high" {
  alarm_name          = "任意の名前"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  period              = 60
  evaluation_periods  = 1
  threshold           = 80
  namespace           = "AWS/ECS"
  metric_name         = "CPUUtilization"
  statistic           = "Maximum"
  dimensions = {
    ClusterName = # クラスタ名を指定
    ServiceName = # サービス名を指定
  }
  alarm_actions = [
    aws_appautoscaling_policy.scale_up_policy.arn
  ]
  tags = # 任意で設定
}


#------------------------------------------------------------------------------
# AWS Auto Scaling - CloudWatch Alarm CPU Low
#------------------------------------------------------------------------------
resource "aws_cloudwatch_metric_alarm" "cpu_low" {
  alarm_name          = "任意の名前"
  comparison_operator = "LessThanOrEqualToThreshold"
  evaluation_periods  = 1
  period              = 60
  metric_name         = "CPUUtilization"
  namespace           = "AWS/ECS"
  statistic           = "Average"
  threshold           = 50
  dimensions = {
    ClusterName = # クラスタ名を指定
    ServiceName = # サービス名を指定
  }
  alarm_actions = [
    aws_appautoscaling_policy.scale_down_policy.arn
  ]
  tags = # 任意で設定
}

メソッド 説明
comparison_operator CloudWatchアラームで、メトリクスの値がしきい値とどのような条件で比較されるかを決める設定。今回は、上限にGreaterThanOrEqualToThreshold、下限にLessThanOrEqualToThresholdを設定
period メトリクスデータを収集する時間間隔を秒単位で指定
evaluation_periods アラームが発動する条件が連続で何回満たされたら反応するかを指定
evaluation_periods 今回はECSのスケールイン、スケールアウトを行う為、ECSを指定
metric_name 何のメトリクスを閾値の基準するか指定する。今回は、CPUUtilizationを指定。変更をする場合は、[AWS公式] Amazon ECS CloudWatch メトリクスを読んで選定する
namespace 何のリソースに対してスケーリングを行うか指定する。今回は、ECSに適用する為、AWS/ECSを記載
threshold 閾値の設定を設定する
statistic CloudWatchアラームで、メトリクスの値をどう計算して判断するかを指定する
dimensions スケーリングさせたいタスクを指定する必要がある為、クラスタとサービスを指定する
alarm_actions CloudWatchアラームの値を参照して、その値が基準値を超えたらコンテナのAuto Scaling機能が動作する。トリガーにするリソースは、構築内容によって変わる

補足説明

ComparisonOperatorの設定項目

ComparisonOperator
The arithmetic operation to use when comparing the specified statistic and threshold. The specified statistic value is used as the first operand.
Required: Yes
Type: String
GreaterThanOrEqualToThreshold(しきい値以上)
GreaterThanThreshold(しきい値より大きい)
LessThanThreshold(しきい値より小さい)
LessThanOrEqualToThreshold(しきい値以下)
LessThanLowerOrGreaterThanUpperThreshold(下限未満または上限超過)
LessThanLowerThreshold(下限未満)
GreaterThanUpperThreshold(上限超過)

statisticの設定の仕方
  • 上限に関しては、設定したCPUの閾値を超えた場合にスケーリングさせる必要がある為、Maximumの設定にする必要がある
  • 下限に関しては、タスク(コンテナ)のCPU値で判断する必要がある。Minimumにすると考える事が多いが、Minimumにするとその設定を下回らない限りスケーリング処理が発生したない為、設定が難しい
  • 下限の設定は、CPUの平均で判断した方が、スケールリング作業が適切に行える為、Averageを設定するのが無難な選択と言える

スケーリングの設定内容

#------------------------------------------------------------------------------
# AWS Auto Scaling - Scaling Up Policy
#------------------------------------------------------------------------------
resource "aws_appautoscaling_policy" "scale_up_policy" {
  name               = "test-scale-up-policy" # 任意の名前
  service_namespace  = "ecs"
  resource_id        = "service/サービス名/クラスター名"
  scalable_dimension = "ecs:service:DesiredCount"
  
  step_scaling_policy_configuration {
    adjustment_type         = "ChangeInCapacity"
    cooldown                = # 任意の数値を記載
    metric_aggregation_type = # "Maximum" or "Average"
    step_adjustment {
      metric_interval_lower_bound = 0
      scaling_adjustment          = 1
    }
  }
  depends_on = [aws_appautoscaling_target.auto_scale_target]
}

#------------------------------------------------------------------------------
# AWS Auto Scaling - Scaling Down Policy
#------------------------------------------------------------------------------
resource "aws_appautoscaling_policy" "scale_down_policy" {
  name               = "test-scale-down-policy" # 任意の名前
  service_namespace  = "ecs"
  resource_id        = "service/サービス名/クラスター名"
  scalable_dimension = "ecs:service:DesiredCount"
  step_scaling_policy_configuration {
    adjustment_type         = "ChangeInCapacity"
    cooldown                = # 任意の数値を記載
    metric_aggregation_type = # "Maximum" or "Average"
    step_adjustment {
      metric_interval_upper_bound = 0
      scaling_adjustment          = -1
    }
  }
  depends_on = [aws_appautoscaling_target.auto_scale_target]
}
メソッド 説明
step_scaling_policy_configuration テップスケーリングポリシーの設定を行うブロック。スケーリングの方法(どのようにリソースを増減させるか)を設定
adjustment_type スケーリング時にリソースの変更をどのように行うかを指定する。ChangeInCapacity はリソースの容量(ここではタスク数)を直接増減させる設定
cooldown スケーリングが行われた後、次のスケーリングアクションが実行されるまでの待機時間を設定
metric_aggregation_type メトリクスの集計方法を指定
step_adjustment スケーリングの調整を行う設定ブロックです。どの程度のリソースを増減させるかを指定
metric_interval_lower_bound スケーリングを行うためのメトリクスの下限値を指定。今回は、CPUが0以上の値でスケールアップするように設定
metric_interval_upper_bound スケーリングを行うためのメトリクスの上限値を指定。今回は、CPUが0以下の値でスケールダウンするように設定
scaling_adjustment スケーリング時にリソース(タスク)の数をどれだけ増減させるかを指定。スケールアップでは1、スケールダウンでは** -1**

下記のメソッドは、cloudwatch-alarmの設定内容で説明している為、省略する

  • service_namespace
  • resource_id
  • scalable_dimension
  • depends_on

補足

metric_aggregation_typeの設定
  • metric_aggregation_typeの選択は、スケーリングの目的やメトリクスの特性によって決まる
項目 Maximum Average
用途 負荷のピーク時に迅速にスケールアップ/ダウンを実行する 全体的な平均負荷に基づいて安定したスケーリングを行う
適している状況 タスクが瞬間的に高負荷を受けた際、即座にリソースを追加して対応するケース。例えば、CPU使用率が急激に上昇した場合、迅速にリソースを拡張して負荷を分散させる際に有効 複数タスクの平均負荷をもとにリソースを調整する。全体の負荷が徐々に増加する際、急激なスケールアップを避け、スムーズに対応するのに最適
特定のタスクで非常に高いCPU負荷が発生した際に、即座にスケールアップして対応する 短期間の負荷ピークに反応せず、全体の平均使用率が高くなってきた時にスケールアップし、低下した際にスケールダウンする

選択の仕方

  • Maximum ; 瞬間的な負荷に対して対応したい場合に選択する
  • Average : 平均的な負荷に基づいて安定したスケーリングを行いたい場合に選択する

参考資料

Terraform

構築時の参考資料

CPU使用率の確認方法

ClowdWatchから確認可能(手順は下記に記載)

  1. CloudWatchの画面を開く
  2. 左側のナビゲーションパネルでメトリクスを選択する
  3. すべてのメトリクスタブを選択する
  4. ECSを展開し、ClusterNameを選択する
  5. クラスター名を選択する
  6. CPUUtilizationメトリクスを選択する

メモリの使用率等も確認可能

参考資料

まとめ

今回は、Terraformを使用して、ECSに対してAuto Scalingを組み込みました。Auto Scalingは、複数の実装方法が存在する為、とても勉強になりました。今回学んだ事を活かして、要件に合わせたAuto Scalingを組み込んでいきたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?