EC2 Auto Scalingでカスタムメトリクスに基づいてスケーリングする構成
以下のページで、定義済みメトリクスに基づいてスケーリングする構成をご紹介しました。
定義済みメトリクスは、以下の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をインストールし、メモリの使用量に基づいてスケーリングさせる構成を作成します。
構築する環境
プライベートサブネット内に、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
テンプレートファイルのポイント解説
今回の構成は、基本的には以下のページと同様です。
本ページは、上記ページとは異なる点にフォーカスします。
カスタムメトリクスのスケーリングポリシー
メモリでスケーリングするためのポリシーを確認します。ポイントは定義済みメトリクス用のプロパティ(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に保存することができます。詳細は以下のページをご確認ください。
今回はメモリ使用量を配信しますので、そちらにフォーカスして確認します。
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プロパティは上記の通りですが、それ以外の設定は、以下のページで紹介されている設定と同様です。
VPCエンドポイント
今回の構成では、プライベートサブネット内にAuto Scalingグループを配置しているため、VPCエンドポイント経由で各種サービスにアクセスする必要があります。
以下に、用途と対応するエンドポイントのサービス名を整理します。
CloudWatchエージェントとApacheのインストール
S3用のエンドポイント(com.amazonaws.${AWS::Region}.s3)を作成します。
今回の構成で作成するインスタンスはAmazon Linux 2ですので、S3バケットで構築されたリポジトリに対して、yumを実行することが可能です。詳細は以下のページをご確認ください。
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スタックを作成します。スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- ALBのDNS名:fa-030-ALB-833774591.ap-northeast-1.elb.amazonaws.com
- ターゲットグループ:fa-030-ALBTargetGroup
AWS Management Consoleからも、リソースの作成状況を確認します。まずAuto Scalingグループを確認します。
正常にAuto Scalingグループが作成されていることがわかります。
このAuto Scalingグループのスケーリングポリシーを確認します。
メモリ使用量でスケーリングする旨が確認できます。
Auto Scalingグループ内のインスタンス状況を確認します。
Activity historyを見ると、確かに希望数通りに、インスタンスが1台作成されていることがわかります。
動作確認1
準備が整いましたので、ALBにアクセスします。
Auto Scalingグループ内のインスタンスから応答がありました。
スケーリング確認
CloudWatchのメトリクスページを見ると、インスタンスのメモリ使用率がスケーリングの閾値(20%)を上回っていることがわかります。
スケーリングが開始されます。
しばらく待つと、スケーリングが完了し、新たなインスタンスが作成されます。
動作確認2
改めてALBにアクセスします。
先ほどのものに加えて、新しいインスタンスにアクセスすることができました。確かにメモリ使用量に基づいてスケーリングが行われました。
まとめ
EC2インスタンス(Amazon Linux 2)にCloudWatch Agentをインストールし、カスタムメトリクス(メモリ使用量)に基づいてスケーリングさせる構成を確認しました。