AWS Compute Optimizer にメモリのメトリクスを含める方法

記事タイトルとURLをコピーする

SRE2課 佐竹です。 コスト削減関連で、AWS Compute Optimizer を再度ご紹介します。

はじめに

以前、ブログ「AWS Compute Optimizer で EC2 Instance を最適化する」の記事で紹介しました「AWS Compute Optimizer」ですが、その記事の中で「CloudWatch Agent 等を利用してメモリの監視データを収集する」ことで、メモリを含めた推奨事項にすることが可能と記載しました。今回はここを掘り下げ AWS Compute Optimizer にメモリのメトリクスを追加する方法と、追加することでどのような変化があったのか記載します。

blog.serverworks.co.jp

Compute Optimizer にメモリのメトリクスを追加する手順

さっそく手順になります。

EC2 Instance に IAM Role を付与する

今回検証用に、1台のEC2を用います。CloudWatchAgent Win2019 というNameタグを付与しています。英語版の Windows Server 2019 になります。まずはこの EC2 Instance に対して、Systems Manager と CloudWatch に関連する IAM Role を付与します。

今回、「SSM-and-CloudWatchAgent」という名称の IAM Role を新規に作成しました。ここに以下の2つのAWSマネージドポリシーをアタッチします。

  1. CloudWatchAgentServerPolicy
  2. AmazonSSMManagedInstanceCore

それぞれ、詳しくはリンク先のAWS公式ドキュメントを参考ください。前者が CloudWatch に利用するもので、後者が SSM で利用するものです。今回 SSM の権限も付与するのは、CloudWatch Agent のインストールを SSM で行いたいためです。

Roleが作成できたら、EC2 Instanceに付与します。

私はよく、作った IAM Role の EC2 Instance への付与を忘れます。Roleの付与忘れには注意してください。

SSM を利用して CloudWatch Agent をインストールする

基本的な作業手順は「公式ドキュメント」に記載がある通りになりますが、画像などを使って補足します。まずは「Systems ManagerのManaged Instances」から対象の EC2 Instance が認識されているか確認します。Windows の AMI には、SSM の Agent がデフォルトでインストールされているため、SSM の IAM Role を付与すれば基本的にこの一覧に表示されます。少し補足しますと、EC2 Insatance に付与されている Security Group では Outbound で 443 が開放されている必要があり、かつ Private Subnet の場合は VPC Endpoint が作成されている必要があります。

Managed Instance の一覧に「 CloudWatchAgent Win2019」が表示されていることが確認できました。次に、「Run Command」のコンソールに移動します。右上の「Run command」ボタンを押下した後、[Command document] リストから、[AWS-ConfigureAWSPackage] を選択します。

次に、Command parameters を入力します。

Action は Install のままで問題ありません。Nameは [AmazonCloudWatchAgent] と手書きしてください。次にターゲットを選択します。

今回は1台だけなので 「Choose instances manually」 で1台だけ選択しました。タグ指定で複数台を串刺しにすることも可能です。SSMでは実行ログをS3に出力可能ですが、今回は割愛します。画面右下の「Run」を押下して実行します。

コマンドが実行されると、このような画面が表示されます。このまま終わるまで待ちましょう。

画面右上のリロードボタンを押していると、すぐにSuccessにステータスが変わると思います。詳細なログが見たい場合は、Instance IDがリンクになっているのでここを押下します。Outputには以下のログが出力されていました。

The command output displays a maximum of 2500 characters. You can view the complete command output in either Amazon S3 or CloudWatch logs, if you specify an S3 bucket or a CloudWatch logs group when you run the command.

Initiating arn:aws:ssm:::package/AmazonCloudWatchAgent 1.246396.0 install
Plugin aws:runPowerShellScript ResultStatus Success
install output: Running install.ps1

Successfully installed arn:aws:ssm:::package/AmazonCloudWatchAgent 1.246396.0

ログを見る限り、無事に成功したようです。

リモートデスクトップ接続して、config.jsonを設定する

ここからはRDP接続をして、OS内部から操作します。

C:\Program Files\Amazon\AmazonCloudWatchAgent

上記のフォルダパスに移動してください。

ここに「config.json」を作成します。config.jsonは、CloudWatch Agentの定義ファイルです。このjsonでどのメトリクスを取得するのか定義を行う必要があります。以下に、今回セットしたサンプルの config.json を記載します。amazon-cloudwatch-agent-config-wizard.exe で対話しながら定義する方法もありますが今回は割愛します。

{
    "agent": {
        "metrics_collection_interval": 60,
        "logfile": "C:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\Logs\\amazon-cloudwatch-agent.log"
    },
    "metrics": {
        "metrics_collected": {
            "Processor": {
                "metrics_collection_interval": 60,
                "measurement": [
                    "% Idle Time",
                    "% Interrupt Time",
                    "% User Time",
                    "% Processor Time"
                ],
                "resources": [
                    "*"
                ]
            },
            "LogicalDisk": {
                "metrics_collection_interval": 60,
                "measurement": [
                    "% Free Space"
                ],
                "resources": [
                    "*"
                ]
            },
            "Memory": {
                "metrics_collection_interval": 60,
                "measurement": [
                    "Available Bytes",
                    "% Committed Bytes In Use"
                ]
            }
        },
        "append_dimensions": {
            "InstanceId": "${aws:InstanceId}",
            "InstanceType": "${aws:InstanceType}"
        },
        "aggregation_dimensions": [
            [
                "InstanceId",
                "InstanceType"
            ],
            []
        ]
    }
}

上記定義では、ローカルに CloudWatch Agent サービスのログを出力するパスを記載しています。これは CloudWatch Agent が正常に動作しているかの調査に重宝するので、基本的には入れておいたほうが良いです。なお、CPUとDisk関係のメトリクスはついでに取りたいため設定しましたが、不要な方はこれらを削除ください。
config.json が完成したら、以下のコマンドを Powershell から実行します。なお Powershell の実行時は、管理者以外でRDPしている場合、「管理者として実行」することを忘れないようにしてください。

cd "C:\Program Files\Amazon\AmazonCloudWatchAgent"
./amazon-cloudwatch-agent-ctl.ps1 -a fetch-config -m ec2 -c file:config.json

この実行により、 config.json がCloudWatch Agent のexeファイルに読み込まれます。この処理を行わない限り、CloudWatch Agent のサービスは開始できません。もし開始しようとすると、以下のエラーが発生します。

Error 1053: The service did not respond to the start or control request in a timely fashion.

また、 json のフォーマットなどに問題がある場合、以下のログが出力されますので json を確認してください。

> ./amazon-cloudwatch-agent-ctl.ps1 -a fetch-config -m ec2 -c file:config.json
 
Successfully fetched the config and saved in C:\ProgramData\Amazon\AmazonCloudWatchAgent\Configs\file_config.json.tmp
Start configuration validation...
2020/07/14 08:43:12 Reading json config file path: C:\ProgramData\Amazon\AmazonCloudWatchAgent\Configs\file_config.json.tmp ...
2020/07/14 08:43:12 Invalid json format, please check. Reason: invalid character '}' after top-level value
2020/07/14 08:43:12 I! AmazonCloudWatchAgent Version 1.246396.0.
2020/07/14 08:43:12 Configuration validation first phase failed. Agent version: 1.246396.0. Verify the JSON input is only using features supported by this version.

成功した場合は、以下の通りのログ出力となります。

> ./amazon-cloudwatch-agent-ctl.ps1 -a fetch-config -m ec2 -c file:config.json
 
Successfully fetched the config and saved in C:\ProgramData\Amazon\AmazonCloudWatchAgent\Configs\file_config.json.tmp
Start configuration validation...
2020/07/14 08:44:43 Reading json config file path: C:\ProgramData\Amazon\AmazonCloudWatchAgent\Configs\file_config.json.tmp ...
Valid Json input schema.
No csm configuration found.
No log configuration found.
Configuration validation first phase succeeded
Configuration validation second phase succeeded
Configuration validation succeeded

補足ですが、CloudWatch Agent の config.json を修正する度に、上記コマンドの実行による再読み込みが必要となります。

Compute Optimizer に必要なメトリクスを知る

AWS Compute Optimizer で分析されたメトリクス

https://docs.aws.amazon.com/ja_jp/compute-optimizer/latest/ug/metrics.html

上記公式ドキュメントにおける「CloudWatch エージェントでのメモリ使用率の有効化」において、以下の記載があります。

Linux インスタンスでは、Compute Optimizer は、CWAgent 名前空間内の mem_used_percent メトリクス、または System/Linux 名前空間内のレガシー MemoryUtilization メトリクスを分析します。Windows インスタンスでは、Compute Optimizer は、CWAgent 名前空間内の Memory % Committed Bytes In Use メトリクスを分析します。さらに、名前空間には InstanceId ディメンションが含まれている必要があります。

今回はWindowsになりますので、「Memory % Committed Bytes In Use」が必須です。これを今回は config.json に含んでいます。 json 内では "% Committed Bytes In Use" と記載します。これを設定に含んでいない場合(つまり Available Bytes メトリクスだけなどの場合)は、Compute Optimizer に適切に利用されません。また、 InstanceId ディメンション が必須であることも注意です。今回は "append_dimensions" 内において、 "InstanceId": "${aws:InstanceId}", を定義しています。

CloudWatch Agent のサービスを起動する

サービス一覧から起動も可能ですが、以下のコマンドで起動を行います。

./amazon-cloudwatch-agent-ctl.ps1 -a start

停止したい場合は、以下の通りです。

./amazon-cloudwatch-agent-ctl.ps1 -a stop

CWAgent のメトリクスを確認する

CloudWatch のコンソールに表示されている「CWAgent」から確認します。

AWS Compute Optimizer に必要な Memory % Committed Bytes In Use メトリクスが、無事に取得されていることが確認できました。

AWS Compute Optimizer の変化を確認する

メモリのメトリクスがあるものとないもので、どのように推奨が変化するのか確認します。ここからは別のAWSアカウントにて検証した結果をお伝えします。

Memory utilization (percent) の値がない場合

Memory utilization (percent) が取得できていない 「Over-provisioned」 の EC2 Instance において、推奨される選択肢は r5.large となっていました。オプション2の t3.xlarge は同じ Instance Type になるため、変化なしです。見て頂くとわかる通り(以前のブログ記事にも記載しましたが)、メモリのメトリクスがない場合は「メモリを下げない」という選択肢で一致しており、vCPU数を下げる方向でのみ推奨となります。

Memory utilization (percent) の値がある場合

Memory utilization (percent) が取得できている場合は 「Over-provisioned」 の EC2 Instance において、推奨される選択肢の1つ目は m5.large となっていました。メモリのメトリクスがある場合は「メモリを下げる」選択肢が増えています。2つ目の選択肢は先ほどと同様に r5.large です。選択肢の1つ目の方がよりコスト削減(最適化)が可能ですので、メモリを含めて AWS Compute Optimizer をみる方がより良いことが証明されました。

まとめ

今回のブログでは、前回「AWS Compute Optimizer で EC2 Instance を最適化する」の記事で紹介しました、「CloudWatch Agent 等を利用してメモリの監視データを収集する」ことで、メモリを含めた推奨事項にすることが可能と記載した件について検証を行いました。検証した結果これが実際にコスト削減に効果的であることが判明しました。以下が今回の検証のために実行した内容のまとめとなります。

  1. EC2 Instance に SSM(Systems Manager) と CloudWatch 用の IAM Role を付与する
  2. SSM を利用し EC2 Instance 内に CloudWatch Agent をインストールする
  3. config.json を設定する
    1. Windows の場合 「Memory % Committed Bytes In Use」を設定する必要がある
    2. InstanceId ディメンション を設定する必要がある
  4. CloudWatch Agent のサービスを起動し、AWS Compute Optimizer に反映されるのを待つ
  5. 結果、メモリのメトリクスを含めたことで「より効果的な推奨オプション」が提示されることが確認できた

補足:RDP せず SSM で全て操作されたい場合は、後日記載しました以下の記事も是非合わせてご覧ください。

blog.serverworks.co.jp


本ブログは以上になります。
それではまたお会いしましょう。

佐竹 陽一 (Yoichi Satake) 記事一覧はコチラ

SRE2課所属。AWS資格12冠。2010年1月からAWSを利用してきました。
AWSのコスト削減、最適化を得意としています。