EC2 Auto Scaling – CPU使用率に基づいてシンプルスケーリング
以下のページでEC2 Auto Scalingの基本事項を取り上げました。
本ページでは、動的スケーリングの挙動を確認します。
EC2 Auto Scalingの動的スケーリングには以下の3種類があります。
- シンプルスケーリング
- ステップスケーリング
- ターゲット追跡スケーリング
今回はシンプルスケーリングの挙動を確認します。
CPU使用率に基づいてインスタンス数をスケーリングします。
なおステップスケーリングに関しては、以下のページをご確認ください。
ターゲット追跡スケーリングに関しては、以下のページをご確認ください。
構築する環境
ALBを作成し、プライベートサブネット内のEC2 Auto Scalingをアタッチします。
Auto Scalingのインスタンス数は以下の通りに設定します。
- 最小数:1
- 最大数:2
- 希望数:1
スケーリングはCPU使用率に応じて実行されるように設定します。
CPU使用率が30%を超えた場合にスケールアウトし、30%未満になった場合はスケールインします。
Auto Scalingグループ内で起動するEC2インスタンスですが、最新版のAmazon Linux 2とします。
S3上のyumリポジトリからApacheをインストールし、Webサーバとして動作するように設定します。
起動したインスタンスにアクセスするために、SSM Session Managerを使用します。
CloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。
https://github.com/awstut-an-r/awstut-fa/tree/main/087
テンプレートファイルのポイント解説
本ページは、EC2 Auto Scalingにおいてシンプルスケーリングを設定する方法を中心に取り上げます。
プライベートサブネット内のリソースをALBにアタッチする方法については、以下のページをご確認ください。
プライベートサブネット内のインスタンスでyumを実行する方法については、以下のページをご確認ください。
(参考)起動テンプレート
Resources:
LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateData:
IamInstanceProfile:
Arn: !GetAtt InstanceProfile.Arn
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
SecurityGroupIds:
- !Ref InstanceSecurityGroup
UserData: !Base64 |
#!/bin/bash -xe
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
ec2-metadata -i > /var/www/html/index.html
LaunchTemplateName: !Sub "${Prefix}-LaunchTemplate"
Code language: YAML (yaml)
起動テンプレートはAuto Scalingグループ内で起動するEC2インスタンスの設定情報に関するリソースです。
EC2 Auto Scalingを構成する上で、起動テンプレートまたは起動設定を作成する必要があります。
ただし現在、起動設定を使用してAuto Scalingを構成することは非推奨となっています。
起動設定を使用しないことを強くお勧めします。Amazon EC2 Auto Scaling または Amazon EC2 には完全な機能を提供していません。起動設定に関する情報は、起動設定から起動テンプレートにまだ移行していないお客様向けに提供しています。
起動設定
基本的にはEC2インスタンスと同様の設定項目です。
例えばImageIdやInstanceTypeプロパティで、起動させるインスタンスのAMIやインスタンスタイプを指定します。
UserDataプロパティでユーザデータを設定できます。
今回はApacheをインストールおよび有効化し、HTMLファイルにインスタンスIDを書き込み、Apacheのルートページに設定します。
Auto Scalingグループ
Resources:
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: !Sub "${Prefix}-AutoScalingGroup"
DesiredCapacity: !Ref DesiredCapacity
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
MaxSize: !Ref MaxSize
MinSize: !Ref MinSize
VPCZoneIdentifier:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
TargetGroupARNs:
- !Ref ALBTargetGroup
Code language: YAML (yaml)
シンプルスケーリングを構成する上で、Auto Scalingグループに特別な設定は不要です。
グループ内に作成するインスタンス数を、以下の通り設定します。
DesiredCapacityプロパティで希望数を1に設定します。
MaxSizeプロパティで最大数を2に設定します。
MinSizeプロパティで最小数を1に設定します。
スケーリングポリシー
Resources:
ScalingPolicy1:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AdjustmentType: ChangeInCapacity
AutoScalingGroupName: !Ref AutoScalingGroup
Cooldown: !Ref Cooldown
PolicyType: SimpleScaling
ScalingAdjustment: !Ref ScalingAdjustment1
ScalingPolicy2:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AdjustmentType: ChangeInCapacity
AutoScalingGroupName: !Ref AutoScalingGroup
Cooldown: !Ref Cooldown
PolicyType: SimpleScaling
ScalingAdjustment: !Ref ScalingAdjustment2
Code language: YAML (yaml)
シンプルスケーリングを構成するためには、2つのスケーリングポリシーを作成します。
1つ目はスケールアウト、2つ目はスケールインするためのポリシーです。
PolicyTypeプロパティにスケーリングポリシーの種類を設定します。
今回はシンプルスケーリングですから、「SimpleScaling」を指定します。
Cooldownプロパティでクールダウン期間を設定できます。
クールダウンの説明は以下に引用した通りです。
Auto Scaling グループは、インスタンスの起動または終了後、クールダウン期間が終了するのを待ってから、シンプルスケーリングポリシーによって開始される追加のスケーリングアクティビティを開始します。クールダウン期間の目的は、以前のアクティビティの効果を確認できるようになる前に、Auto Scaling グループが追加のインスタンスを起動または終了しないようにすることです。
Amazon EC2 Auto Scaling のスケーリングクールダウン
今回は「300」を指定し、次のスケーリングが発生するまで5分待機します。
ScalingAdjustmentプロパティは調整値に関するパラメータです。
スケーリングが実行される際に、Auto Scalingグループ内のインスタンス数を増減する量です。
今回は2ポリシーに対して、それぞれ「1」および「-1」を指定します。
AdjustmentTypeプロパティでスケーリング調整タイプを設定します。
今回は「ChangeInCapacity」を指定します。
このタイプの説明は以下に引用した通りです。
ChangeInCapacity – 指定した値だけ現在のキャパシティーを増減させます。正の調整値は現在のキャパシティーを増やし、負の調整値は現在のキャパシティーを減らします。たとえば、グループの現在のキャパシティーが 3 で、調整値が 5 の場合、このポリシーが実行されると、キャパシティーユニットが 5 個キャパシティーに追加され、合計 8 個のキャパシティーユニットになります。
スケーリング調整タイプ
今回の設定ですと、通常時はグループ内に1台インスタンスが起動していますが、スケールアウト時は1つ追加で起動して2台構成になり、スケールイン時は1台削除されて1台構成になるという挙動になります。
CloudWatchアラーム
Resources:
Alarm1:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmActions:
- !Ref ScalingPolicy1
AlarmName: !Sub "${Prefix}-Alarm1"
ComparisonOperator: GreaterThanOrEqualToThreshold
Dimensions:
- Name: AutoScalingGroupName
Value: !Ref AutoScalingGroup
EvaluationPeriods: !Ref AlarmEvaluationPeriod
MetricName: CPUUtilization
Namespace: AWS/EC2
Period: !Ref AlarmPeriod
Statistic: Average
Threshold: !Ref AlarmThreshold
Alarm2:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmActions:
- !Ref ScalingPolicy2
AlarmName: !Sub "${Prefix}-Alarm2"
ComparisonOperator: LessThanOrEqualToThreshold
Dimensions:
- Name: AutoScalingGroupName
Value: !Ref AutoScalingGroup
EvaluationPeriods: !Ref AlarmEvaluationPeriod
MetricName: CPUUtilization
Namespace: AWS/EC2
Period: !Ref AlarmPeriod
Statistic: Average
Threshold: !Ref AlarmThreshold
Code language: YAML (yaml)
CloudWatchアラームはスケーリングポリシーが動作するきっかけとして作用します。
アラームはスケーリングポリシーごとに作成します。
1つ目のアラームはスケールアウトポリシー用、2つ目のアラームはスケールインポリシー用です。
これはAlarmActionsプロパティで指定します。
Dimensionsプロパティでメトリックを計測する対象を設定します。
今回はAuto ScalingグループのCPU使用率を計測するために、Nameに「AutoScalingGroupName」を、ValueにグループのIDを指定します。
今回はCPU使用率に応じてスケーリングが開始されるように設定します。
MetricNameプロパティに「CPUUtilization」、Namespaceプロパティに「AWS/EC2」、Statisticプロパティに「Average」を指定することによって、Auto Scalingグループ全体のCPU使用率の平均値を計測します。
CPU使用率の計測期間はPeriodプロパティで設定します。
今回は「60」を指定して、1分ごとに計測します。
ComparisonOperator・Threshold・EvaluationPeriodsプロパティで閾値を設定します。
アラーム1では、それぞれ「GreaterThanOrEqualToThreshold」、「30」、「2」を指定して、CPU使用率が2回連続で30%以上になった場合に発動します。
アラーム2では、それぞれ「LessThanOrEqualToThreshold」、「30」、「2」を指定して、CPU使用率が2回連続で30%以下になった場合に発動します。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- ALB:fa-087-ALB
- ALBのDNS名:fa-087-alb-737613323.ap-northeast-1.elb.amazonaws.com
- ALBのターゲットグループ:fa-087-ALBTargetGroup
- 起動テンプレート:fa-087-LaunchTemplate
- EC2 Auto Scalingグループ:fa-087-AutoScalingGroup
- CloudWatchアラーム1:fa-087-Alarm1
- CloudWatchアラーム2:fa-087-Alarm2
作成されたリソースをAWS Management Consoleから確認します。
ALBを確認します。
ALBのDNS名等が確認できます。
Auto Scalingグループを確認します。
希望数・最小数が1、最大数が2です。つまりAuto Scalingグループ内に、通常時は1つ、スケールアウト時は2つのインスタンスが起動します。
スケーリングポリシーを確認します。
2つのスケーリングポリシーが作成されていることがわかります。
スケールアウト/イン用のポリシーです。
2つのポリシーが動作するきっかけであるCloudWatchアラームが発動する条件も確認することができます。
Auto Scalingグループのアクティビティ履歴を見ると、空だったグループ内にインスタンスが1つ作成されたことがわかります。
グループ内のインスタンスを確認すると、確かにインスタンスが1つ起動していることがわかります。
現時点のCPU使用率は以下の通りです。
CPU使用率が30%未満ですから、スケールアウトが開始されません。
動作確認
通常時
準備が整いましたので、ALBにアクセスします。
インスタンスにアクセスできました。
確かにALBにAuto Scalingグループがアタッチされていることがわかります。
スケールアウト
スケールアウト時の挙動を確認します。
SSM Session Managerを使用して、Auto Scalingグループ内のインスタンスにアクセスします。
% aws ssm start-session --target i-013a345e86bf1eda1
Starting session with SessionId: root-0d5c2cb28ca211e00
sh-4.2$
Code language: Bash (bash)
SSM Session Managerの詳細につきましては、以下のページをご確認ください。
yesコマンドを使用して、インスタンスのCPU使用率を高めます。
sh-4.2$ yes > /dev/null &
Code language: Bash (bash)
しばらく待機すると、CPU使用率が30%を超えます。
これでスケールアウトが開始される条件を満たしました。
Auto Scalingグループのアクティビティ履歴を見ると、新たなインスタンスが起動したことがわかります。
グループ内のインスタンスを確認すると、確かにインスタンスが2つ起動していることがわかります。
改めてALBにアクセスします。
1台目に加えて、2台目のインスタンスにも交互にアクセスすることができました。
以上の通り、スケールアウト用ポリシーが動作し、Auto Scalingグループ内に2つ目のインスタンスが生成されたことがわかりました。
スケールイン
スケールイン時の挙動を確認するために、しばらく待機します。
2台目のインスタンスが起動したことで、Auto Scalingグループ全体のCPU使用率の平均値が30%を下回りました。
これでスケールインが開始される条件を満たしました。
Auto Scalingグループのアクティビティ履歴を見ると、インスタンスが1台削除されたことがわかります。
グループ内のインスタンスを確認すると、確かにインスタンスが1つ起動していることがわかります。
削除されたインスタンスは、yesコマンドでCPU使用率を高めていたインスタンスです。
改めてCPU使用率を確認します。
CPU使用率が1%未満に戻りました。
現在起動しているインスタンスでは、yesコマンド等は実行していないためです。
以上の通り、スケールイン用ポリシーが動作し、Auto Scalingグループ内の1台のインスタンスが削除されたことがわかりました。
まとめ
EC2 Auto Scalingの動的スケーリングの一種であるシンプルスケーリングの挙動を確認しました。