カスタムメトリクス(メモリ)に基づいたスケーリング(Linux)

目次

EC2 Auto Scalingでカスタムメトリクスに基づいてスケーリングする構成

以下のページで、定義済みメトリクスに基づいてスケーリングする構成をご紹介しました。

あわせて読みたい
EC2 Auto Scaling ターゲット追跡ポリシーの4つの定義済みメトリクス 【全ての定義済みメトリクスに基づいたスケーリングを確認する構成】 EC2 Auto Scaling入門ということで、以下のページでCPU使用率に基づいて、インスタンス数をスケー...

定義済みメトリクスは、以下の4つが用意されています。

・ASGAverageCPUUtilization – Auto Scaling グループの平均 CPU 使用率。

・ASGAverageNetworkIn – すべてのネットワークインターフェイスで Auto Scaling グループが受信した平均バイト数。

・ASGAverageNetworkOut – すべてのネットワークインターフェイスで Auto Scaling グループが送信した平均バイト数。

・ALBRequestCountPerTarget – Application Load Balancer ターゲットグループ内のターゲットごとに完了したリクエストの数。

Amazon EC2 Auto Scaling のターゲットトラッキングスケーリングポリシー

上記以外のメトリックを使用する場合は、カスタムメトリクスを指定することができます。
今回はEC2インスタンス(Amazon Linux 2)にCloudWatch Agentをインストールし、メモリの使用量に基づいてスケーリングさせる構成を作成します。

構築する環境

Diagram of Custom Metrics Scaling by Memory Utilization Linux Version

プライベートサブネット内に、EC2 Auto Scalingグループを作成します。グループ内で起動するインスタンスは、Apacheをインストールし、Webサーバとして動作させます。
各種VPCエンドポイントを作成します。ApacheおよびCloudWatchエージェントをインストールするために、S3およびSSM用のエンドポイント、カスタムメトリクスを送信するためにCloudWatch用エンドポイントを作成します。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。以下のURLにCloudFormationテンプレートを配置してます。

https://github.com/awstut-an-r/awstut-fa/tree/main/030

テンプレートファイルのポイント解説

今回の構成は、基本的には以下のページと同様です。

あわせて読みたい
EC2 Auto Scaling – CPU使用率に基づいてターゲット追跡スケーリング 【EC2 Auto Scaling - CPU使用率に基づいてターゲット追跡スケーリング】 以下のページでEC2 Auto Scalingの基本事項を取り上げました。 https://awstut.com/2022/10/08...

本ページは、上記ページとは異なる点にフォーカスします。

カスタムメトリクスのスケーリングポリシー

メモリでスケーリングするためのポリシーを確認します。ポイントは定義済みメトリクス用のプロパティ(PredefinedMetricSpecification)ではなく、カスタムメトリクス用のプロパティ(CustomizedMetricSpecification)を設定する点です。

Resources:
  ScalingPolicy:
    Type: AWS::AutoScaling::ScalingPolicy
    Properties:
      AutoScalingGroupName: !Ref AutoScalingGroup
      PolicyType: TargetTrackingScaling
      TargetTrackingConfiguration:
        CustomizedMetricSpecification:
          Dimensions:
            - Name: AutoScalingGroupName
              Value: !Ref AutoScalingGroupName
          MetricName: mem_used_percent
          Namespace: CWAgent
          Statistic: Average
          Unit: Percent
        TargetValue: !Ref TargetTrackingConfigurationTargetValue
Code language: YAML (yaml)

設定内容はAWS公式ページを参考にしました。

Dimensionsプロパティでディメンションを指定します。今回はAutoScalingGroupNameという名前で、グループ名を値として設定します。この値は、後述のCloudWatchエージェントで設定するディメンション設定と合わせる必要があります。
MetricNameプロパティで、収集するメトリック名を指定します。今回はCloudWatchエージェントでメモリ使用率を収集するために、この項目名である「mem_used_percent」を設定します。
StatisticおよびUnitプロパティで、取得する値のパラメータを定めます。今回はメモリ使用率の平均値を取得するため、それぞれ「Average」、「Percent」を指定します。
最後に、TargetValueプロパティで閾値を設定します。今回はメモリ使用率20%を条件に、スケーリングを行うように設定します。

メモリ使用量を配信するためのCloudWatchエージェントコンフィグ

CloudWatchエージェントの設定ですが、SSM Parameter Storeに保存することができます。詳細は以下のページをご確認ください。

あわせて読みたい
LinuxにCloudWatch Agentをインストールしてデータ収集 【LinuxインスタンスにCloudWatch Agentをインストールして、ログとメトリクスを収集する構成】 CloudWatch Agentを使用することによって、ログやメトリクスを収集する...

今回はメモリ使用量を配信しますので、そちらにフォーカスして確認します。

Resources:
  CloudWatchConfigParemeter:
    Type: AWS::SSM::Parameter
    Properties:
      Name: AmazonCloudWatch-linux
      Type: String
      Value: |
        {
          "agent": {
            "metrics_collection_interval": 60,
            "run_as_user": "root"
          },
          "metrics": {
            "append_dimensions": {
              "ImageId": "${aws:ImageId}",
              "InstanceId": "${aws:InstanceId}",
              "InstanceType": "${aws:InstanceType}",
              "AutoScalingGroupName": "${aws:AutoScalingGroupName}"
            },
            "metrics_collected": {
              "mem": {
                "measurement": [
                  "mem_used_percent"
                ],
                "metrics_collection_interval": 60
              }
            },
            "aggregation_dimensions": [["AutoScalingGroupName"]]
          }
        }
Code language: YAML (yaml)

「append_dimensions」に、先述の「AutoScalingGroupName」を設定します。
「metrics_collected」でメモリ使用量に関する設定を行います。使用量のメトリック名は「mem_used_percent」です。
Auto Scalingグループ用の設定でポイントとなるものは、「aggregation_dimensions」です。

収集されたメトリクスが集計されるディメンションを指定します。例えば、AutoScalingGroupName ディメンションでメトリクスをロールアップした場合、各 Auto Scaling グループ内のすべてのインスタンスのメトリクスが集約され、全体として参照できるようになります。

CloudWatch エージェント設定ファイル: Metrics セクション

Auto Scalingグループ名を指定することで、グループ内の複数のインスタンスを総合した上で、メモリ使用量を計算するという挙動になります。

SSMドキュメントを実行してインスタンス初期化

AWSによって事前定義された3種類のSSMドキュメントを使用して、インスタンスのセットアップを行います。

AWS-ConfigureAWSPackageとAmazonCloudWatch-ManageAgent

CloudWatchエージェントのインストールと起動をSSMドキュメントから実行します。
基本的には、先述のページと同様の設定です。

ポイントは対象インスタンスの指定方法です。Targetsプロパティで対象を指定しますが、今回はインスタンスに付与されるタグを使用します。Auto Scalingグループ内に作成されたインスタンスは、自動的に、以下のタグが付与されます。

  • タグ名:aws:autoscaling:groupName
  • 値:[Auto Scalingグループ名]

Targetsプロパティにタグを指定する場合、「tag:[tag-name]」という形式で指定する必要がありますので、Keyプロパティに「tag:aws:autoscaling:groupName」と設定します。
このように自動的に付与されるタグを使って、対象のインスタンスを指定することによって、新規にAuto Scalingグループ内に作成されたインスタンスに対しても、自動的に本ドキュメントが実行されることになります。

AWS-RunShellScript

インスタンスをWebサーバとして動作させるための設定です。
Targetsプロパティは上記の通りですが、それ以外の設定は、以下のページで紹介されている設定と同様です。

あわせて読みたい
Linuxインスタンスの初期化方法4選 【Linuxインスタンスを初期化する4つの方法】 EC2インスタンスの起動時に初期化処理を実行する方法を考えます。 EC2インスタンスを構築時に初期化する以下の4つの手法を...

VPCエンドポイント

今回の構成では、プライベートサブネット内にAuto Scalingグループを配置しているため、VPCエンドポイント経由で各種サービスにアクセスする必要があります。
以下に、用途と対応するエンドポイントのサービス名を整理します。

CloudWatchエージェントとApacheのインストール

S3用のエンドポイント(com.amazonaws.${AWS::Region}.s3)を作成します。
今回の構成で作成するインスタンスはAmazon Linux 2ですので、S3バケットで構築されたリポジトリに対して、yumを実行することが可能です。詳細は以下のページをご確認ください。

あわせて読みたい
プライベートサブネットのインスタンスでyum/dnfを実行する 【プライベートサブネット内のインスタンスでyum/dnfを実行する構成】 プライベートサブネット内のインスタンスで、yum/dnfを実行する方法を確認します。 今回は以下の2...

SSMドキュメント実行

2つのエンドポイントを作成します。

  • com.amazonaws.${AWS::Region}.ssm
  • com.amazonaws.${AWS::Region}.ec2messages

なお作成されたインスタンスにSSM Session Managerでアクセスする場合は、追加でcom.amazonaws.${AWS::Region}.ssmmessagesも作成します。

CloudWatchエージェントでメトリクス配信

2つのエンドポイントを作成します。

  • com.amazonaws.${AWS::Region}.monitoring
  • com.amazonaws.${AWS::Region}.ec2

なおCloudWatchエージェントでログも配信したい場合は、追加でcom.amazonaws.${AWS::Region}.logsも作成します。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

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

  • ALBのDNS名:fa-030-ALB-833774591.ap-northeast-1.elb.amazonaws.com
  • ターゲットグループ:fa-030-ALBTargetGroup

AWS Management Consoleからも、リソースの作成状況を確認します。まずAuto Scalingグループを確認します。

Auto Scaling group has been successfully created.

正常にAuto Scalingグループが作成されていることがわかります。

このAuto Scalingグループのスケーリングポリシーを確認します。

Scaling policy based on memory utilization.

メモリ使用量でスケーリングする旨が確認できます。

Auto Scalingグループ内のインスタンス状況を確認します。

One instance is created in the Auto Scaling group.

Activity historyを見ると、確かに希望数通りに、インスタンスが1台作成されていることがわかります。

動作確認1

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

Access to the first instance.

Auto Scalingグループ内のインスタンスから応答がありました。

スケーリング確認

CloudWatchのメトリクスページを見ると、インスタンスのメモリ使用率がスケーリングの閾値(20%)を上回っていることがわかります。

Memory utilization exceeds the scaling threshold.

スケーリングが開始されます。

A second instance was created.

しばらく待つと、スケーリングが完了し、新たなインスタンスが作成されます。

動作確認2

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

Access to the second instance.

先ほどのものに加えて、新しいインスタンスにアクセスすることができました。確かにメモリ使用量に基づいてスケーリングが行われました。

まとめ

EC2インスタンス(Amazon Linux 2)にCloudWatch Agentをインストールし、カスタムメトリクス(メモリ使用量)に基づいてスケーリングさせる構成を確認しました。

目次