EC2 Auto Scaling – CPU使用率に基づいてシンプルスケーリング

EC2 Auto Scaling - CPU使用率に基づいてシンプルスケーリング

EC2 Auto Scaling – CPU使用率に基づいてシンプルスケーリング

以下のページでEC2 Auto Scalingの基本事項を取り上げました。

https://awstut.com/2022/10/08/introduction-to-ec2-auto-scaling-no-scaling-policy

本ページでは、動的スケーリングの挙動を確認します。
EC2 Auto Scalingの動的スケーリングには以下の3種類があります。

  • シンプルスケーリング
  • ステップスケーリング
  • ターゲット追跡スケーリング

今回はシンプルスケーリングの挙動を確認します。
CPU使用率に基づいてインスタンス数をスケーリングします。

なおステップスケーリングに関しては、以下のページをご確認ください。

https://awstut.com/2022/10/10/ec2-auto-scaling-step-scaling-based-on-cpu-utilization

ターゲット追跡スケーリングに関しては、以下のページをご確認ください。

https://awstut.com/2022/02/20/ec2-auto-scaling-target-tracking-policy-cpu-utilization

構築する環境

Diagram of EC2 Auto Scaling - Simple Scaling based on CPU utilization

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にアタッチする方法については、以下のページをご確認ください。

https://awstut.com/2021/11/28/attach-private-ec2-to-elb

プライベートサブネット内のインスタンスでyumを実行する方法については、以下のページをご確認ください。

https://awstut.com/2021/12/01/yum-in-private-subnet

(参考)起動テンプレート

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スタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

https://awstut.com/2021/12/02/cloudformation-nested-stacks

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • 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を確認します。

Detail of ALB 1.

ALBのDNS名等が確認できます。

Auto Scalingグループを確認します。

Detail of EC2 Auto Scaling 1.

希望数・最小数が1、最大数が2です。つまりAuto Scalingグループ内に、通常時は1つ、スケールアウト時は2つのインスタンスが起動します。

スケーリングポリシーを確認します。

Detail of EC2 Auto Scaling 2.

2つのスケーリングポリシーが作成されていることがわかります。
スケールアウト/イン用のポリシーです。
2つのポリシーが動作するきっかけであるCloudWatchアラームが発動する条件も確認することができます。

Detail of EC2 Auto Scaling 3.

Auto Scalingグループのアクティビティ履歴を見ると、空だったグループ内にインスタンスが1つ作成されたことがわかります。

Detail of EC2 Auto Scaling 4.

グループ内のインスタンスを確認すると、確かにインスタンスが1つ起動していることがわかります。

現時点のCPU使用率は以下の通りです。

Detail of EC2 Auto Scaling 5.

CPU使用率が30%未満ですから、スケールアウトが開始されません。

動作確認

通常時

準備が整いましたので、ALBにアクセスします。

Detail of ALB 2.

インスタンスにアクセスできました。
確かに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の詳細につきましては、以下のページをご確認ください。

https://awstut.com/2021/12/01/ssm-session-manager-linux

yesコマンドを使用して、インスタンスのCPU使用率を高めます。

sh-4.2$ yes > /dev/null &
Code language: Bash (bash)

しばらく待機すると、CPU使用率が30%を超えます。
これでスケールアウトが開始される条件を満たしました。

Detail of EC2 Auto Scaling 7.

Auto Scalingグループのアクティビティ履歴を見ると、新たなインスタンスが起動したことがわかります。

Detail of EC2 Auto Scaling 8.

グループ内のインスタンスを確認すると、確かにインスタンスが2つ起動していることがわかります。

改めてALBにアクセスします。

Detail of EC2 Auto Scaling 9.

1台目に加えて、2台目のインスタンスにも交互にアクセスすることができました。
以上の通り、スケールアウト用ポリシーが動作し、Auto Scalingグループ内に2つ目のインスタンスが生成されたことがわかりました。

スケールイン

スケールイン時の挙動を確認するために、しばらく待機します。

Detail of EC2 Auto Scaling 10.

2台目のインスタンスが起動したことで、Auto Scalingグループ全体のCPU使用率の平均値が30%を下回りました。
これでスケールインが開始される条件を満たしました。

Detail of EC2 Auto Scaling 11.

Auto Scalingグループのアクティビティ履歴を見ると、インスタンスが1台削除されたことがわかります。

Detail of EC2 Auto Scaling 12.

グループ内のインスタンスを確認すると、確かにインスタンスが1つ起動していることがわかります。
削除されたインスタンスは、yesコマンドでCPU使用率を高めていたインスタンスです。

改めてCPU使用率を確認します。

Detail of EC2 Auto Scaling 13.

CPU使用率が1%未満に戻りました。
現在起動しているインスタンスでは、yesコマンド等は実行していないためです。
以上の通り、スケールイン用ポリシーが動作し、Auto Scalingグループ内の1台のインスタンスが削除されたことがわかりました。

まとめ

EC2 Auto Scalingの動的スケーリングの一種であるシンプルスケーリングの挙動を確認しました。