概要
表題の通り、Terraform
を用いて自動スケーリング機能を追加しました。本記事では、その具体的な実装方法について記述します。
Auto Scalingの種類
- Auto Scalingは、主に3種類の設定項目がある為、各機能について説明する
ターゲット追跡ポリシ
- システムのパフォーマンスを安定させる為に、
CPU
使用率を目標値に保つ様、コンテナ数を自動的に調整する - 指定したメトリクス(例:
CPU
使用率、メモリ使用量)が設定した目標値を超えるか下回った際、自動的にスケールイン(リソースを減らす)またはスケールアウト(リソースを増やす)を行う -
AWS
が提供するマネージドサービスであり、導入が比較的容易 -
AWS
が推奨するスケーリング方法
ステップスケーリングポリシ
- リソースの使用率の変化に対してより細かく閾値を決めてスケールイン、アウトを行う
-
CloudWatch
アラームをトリガーとして、CPU
使用率が特定の閾値を超過するか、閾値未満になるとアラームが発生し、それに応じたスケーリングアクションが実行される - スケールアウトはリソースを追加するだけなので比較的容易に設定出来るが、スケールインはリソース削減に伴うパフォーマンス低下やコスト増加のリスクがある為、設定が複雑になる
- 閾値を適切に設定をする必要がある為、導入が難しいが、詳細にスケーリングを調整したい場合に便利
スケジュールに基づくスケーリング
- 指定した日時に基づいて、タスク数を増減させる
- 他のスケーリングポリシと組み合わせて利用可能
参考資料
- [AWS公式] Amazon ECS と Application Auto Scaling
- [AWS公式] Amazon ECS サービスを自動的にスケールする
- [AWS公式] ターゲット追跡スケーリングポリシー
- [AWS公式] ステップスケーリングポリシ
- [AWS公式] スケジュールに基づくスケーリング
- ECSにおけるAuto Scaling Policyの「ターゲットスケーリング」と「ステップスケーリング」について
- Auto Scaling ターゲット追跡ポリシー VS ステップスケーリングポリシー
- ECSで通常時とスパイク時のオートスケールを運用する
- [Terraform]ECS Fargateのオートスケーリング設定
構築手法
- 下記の構築内容は、ターゲット追跡ポリシ、スケーリングポリシのどちらでも使用する
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
構築時の参考資料
- RegisterScalableTarget(スケーラブルを登録する)
- PredefinedScalingMetricSpecification
- ECS Fargate Terraform オートスケーリングの2つの方法について、まとめてみた(コードあり)
- terraform import: ECS / Application Auto Scaling
- Terraformでターゲット追跡スケーリングポリシーのAuto Scalingを実装する
スケーリングポリシの構築
-
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
構築時の参考資料
- [AWS公式] Amazon ECS CloudWatch メトリクス
- [AWS公式] CloudWatch 統計定義
- [AWS公式] Amazon EC2 Auto Scaling のスケーリングのクールダウン
- Amazon EC2 Auto Scaling のステップおよびシンプルなスケーリングポリシー
- [Terraform]ECS Fargateのオートスケーリング設定
CPU使用率の確認方法
ClowdWatchから確認可能(手順は下記に記載)
-
CloudWatch
の画面を開く - 左側のナビゲーションパネルでメトリクスを選択する
- すべてのメトリクスタブを選択する
-
ECS
を展開し、ClusterName
を選択する - クラスター名を選択する
-
CPUUtilization
メトリクスを選択する
メモリの使用率等も確認可能
参考資料
まとめ
今回は、Terraform
を使用して、ECS
に対してAuto Scaling
を組み込みました。Auto Scaling
は、複数の実装方法が存在する為、とても勉強になりました。今回学んだ事を活かして、要件に合わせたAuto Scaling
を組み込んでいきたいと思います。