今回はAWS SSM(Systems Manager エージェント)を使ってCloudWatchエージェントをインストールして、EC2インスタタンスの性能情報をしてみようと思います。
CloudWatchエージェントを使用することにより、標準メトリクスでは取得できない性能情報(メモリ使用率、ディスク使用率など)をカスタムメトリクスとして取得することができます。
環境構成図
今回検証するための環境構成は下記のようになります。
CloudWatchエージェントをプライベートサブネット用のEC2インスタンスに導入し、
VPCエンドポイント経由でSSMやCloudWatchと通信します。
適宜必要なパッケージ類はパブリックサブネットのNATゲートウェイ経由で外部リポジトリから導入できるようにしてます。
※今回NATゲートウェイを作成するところの記載は割愛しております。
EC2のインスタンスは今回RHEL8.4を使用。

1.IAMロールの設定
まず、SSMを使ってEC2にCloud CloudwatchエージェントをインストールしたりエージェントがメトリクスをCloudwatchに送信するために以下のポリシーをロールにアタッチし、EC2に割り当てる必要があります。
【必要なポリシー】
CloudWatchAgentServerPolicy
CloudWatchAgentAdminPolicy
AmazonEC2RoleforSSM ※1
(※1 AmazonEC2RoleforSSMは権限の範囲が広すぎるとのことなので現在はAmazonSSMManagedInstanceCoreを推奨しているそうです。)
ではさっそくロールを作成していきます。

一般的なユースケースからEC2を選択し、「次のステップ:アクセス権限」を押下。

ポリシーのフィルタに今回アタッチするポリシー名で検索し、左のチェックを付ける。
※アタッチ対象のポリシー分実施します。(今回は3つ分)
チェックし終わったら「次のステップ:タグ」を押下。

タグは任意で設定します。(今回は特に設定しなくてもおk)
次のステップにいくと確認画面が表示されるのでロール名を設定します。
ポリシーに今回アタッチする3つのポリシーが表示されていることを確認したら「ロールの作成」を押下します。

ロールの作成が完了したらEC2インスタンスにアタッチします。

2.SSMエージェントのインストール
EC2インスタンスにSSMエージェントをインストールしていきます。
まずSSMエージェント導入の前提としてpython2か3が入っていることが条件ですのでそれを確認します。
※何も表示されない場合はpython3を個別に導入してください。
# python3 --version
SSMエージェントをインストールします。
# dnf install -y https://s3.ap-northeast-1.amazonaws.com/amazon-ssm-ap-northeast-1/latest/linux_amd64/amazon-ssm-agent.rpm
インストール後、SSMエージェントが起動していることを確認。
# systemctl status amazon-ssm-agent

3.VPCエンドポイントの設定
プライベートサブネットからSSMやCloudWatchと通信するために下記サービスのエンドポイントが必要になります。
【サービス名】
com.amazonaws.ap-northeast-1.ssm
com.amazonaws.ap-northeast-1.ssmmessages
com.amazonaws.ap-northeast-1.ec2
com.amazonaws.ap-northeast-1.ec2messages
com.amazonaws.ap-northeast-1.monitoring
エンドポイントの作成を作成していきます。
サービス名は上記から1つ検索チェックし、
対象となるVPC、サブネットを選びます。

プライベートDNS名を有効にするにはチェックを入れます(デフォルトでついてます。)

セキュリティグループを割り当てます。
必要な定義は以下となるので新規作成か既存SGに下記を設定します。
【インバウントルール】
プロトコル:TCP
ポート範囲:443
ソース:EC2インスタンスのIP(今回でいうと10.0.11.22/32)

エンドポインの作成を押下します。

これを上記サービス名分のエンドポイントを作成します。(まとめて作成する方法ないのかな・・・)
4.CloudWatchエージェントのインストール&設定
SSMを使ってEC2へCloudWatchエージェントをインストールしていきます。
SSMサービスの画面に行ったら「Run Command」を実行します。

パッケージ配布機能である「AWS-ConfigureAWSPackage」を選択します。

下記についてそれぞれ入力していきます。
Action: install
Installation Type: Uninstall and reinstall
Name: AmazonCloudWatchAgent
Version: latest

ターゲットは「インスタンスを手動で選択する」を選択し、
対象のECインスタンスにチェックします。

今回はS3バケットにログを出力させないので書き込みの有効化はチェック外し、
「実行」を押下します。

コマンドが正常終了していることが分かります。

EC2にログインして、CloudWatchサービスの起動状態を確認します。
サービスとして認識されているのでインストールはできてますがinactive状態です。
(パラメータファイルがないので起動できない状態です。)
# systemctl status amazon-cloudwatch-agent.service -l ● amazon-cloudwatch-agent.service - Amazon CloudWatch Agent Loaded: loaded (/etc/systemd/system/amazon-cloudwatch-agent.service; disabled; vendor preset: disabled) Active: inactive (dead)
次にCloudWatchのパラメータファイルをコンフィグウィザードで作成していきます。
# /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
CloudWatchエージェントをどのOSで使用するか問われているのでlinuxの1を選択。
On which OS are you planning to use the agent?
1. linux
2. windows
3. darwin
default choice: [1]: 1
CloudWatchどの環境で使用するか、EC2かオンプレかをと問われているのでEC2の1を選択。
Trying to fetch the default region based on ec2 metadata...
Are you using EC2 or On-Premises hosts?
1. EC2
2. On-Premises
default choice: [1]: 1
CloudWatchエージェントをどのユーザで実行するか。
今回はrootで実行しようと思うので1を選択。
Which user are you planning to run the agent?
1. root
2. cwagent
3. others
default choice: [1]: 1
StatusDというossな情報採取ツールらしいですが、これがないとカスタムメトリクスによる取得ができないっぽいのでyesの1を選択。
Do you want to turn on StatsD daemon?
1. yes
2. no
default choice: [1]: 1
先ほどのStatsDで使用するポート。今回はデフォルトの8125で。(他と被ってなさそうだった。)
Which port do you want StatsD daemon to listen to? default choice: [8125]
StatsDの収集間隔の指定。デフォルトの10秒である1を選択。
What is the collect interval for StatsD daemon?
1. 10s
2. 30s
3. 60s
default choice: [1]: 1
StatsDによって収集されるデータの時間間隔の指定。デフォルトの60秒である4を選択。
What is the aggregation interval for metrics collected by StatsD daemon?
1. Do not aggregate
2. 10s
3. 30s
4. 60s
default choice: [4]: 4
CollectD?(どうやらStatsDとはまた別の情報採取ツールらしい・・・)
これがないとディスク使用率、メモリ使用率などが取得できないっぽいのでyesの1を選択。
Do you want to monitor metrics from CollectD?
1. yes
2. no
default choice: [1]: 1
ホストメトリクスを取得するかどうか。
ホストメトリクスにシステムメトリック(CPU、ネットワーク)とカスタムメトリクス(memory、ディスク使用率)が含まれるのでyesの1を選択。
Do you want to monitor any host metrics? e.g. CPU, memory, etc.
1. yes
2. no
default choice: [1]: 1
CPUコア単位で使用率を取得するか。取得するのでyesの1を選択。
Do you want to monitor cpu metrics per core? Additional CloudWatch charges may apply.
1. yes
2. no
default choice: [1]: 1
ImageId、InstanceId、InstanceType、AutoScalingGroupNameを取得可能であれば取得するか。
取得するのでyesの1を選択。
Do you want to add ec2 dimensions (ImageId, InstanceId, InstanceType, AutoScalingGroupName) into all of your metrics if the info is available?
1. yes
2. no
default choice: [1]: 1
メトリクスの取得間隔。(さっきも同じようなのでてきた気がするが・・・)
デフォルトである60秒の4を選択。
Would you like to collect your metrics at high resolution (sub-minute resolution)? This enables sub-minute resolution for all metrics, but you can customize for specific metrics in the output json file.
1. 1s
2. 10s
3. 30s
4. 60s
default choice: [4]: 4
デフォルトでどのメトリクスを取得するか。(取得できる情報数に松竹梅あるようなイメージ。)
公式サイト(https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-cloudwatch-agent-configuration-file-wizard.html)を見るとディスクIOが「Advanced」で見れるようなので3を選択。
Which default metrics config do you want?
1. Basic
2. Standard
3. Advanced
4. None
default choice: [1]: 3
今までの定義内容が表示されでこれでおk?と問われている。
ウィザード完了後も定義を追加できたりしますよとのこと。
yesの1を選択。
Current config as follows:
{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "root"
},
"metrics": {
"append_dimensions": {
"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
"ImageId": "${aws:ImageId}",
"InstanceId": "${aws:InstanceId}",
"InstanceType": "${aws:InstanceType}"
},
"metrics_collected": {
"collectd": {
"metrics_aggregation_interval": 60
},
"cpu": {
"measurement": [
"cpu_usage_idle",
"cpu_usage_iowait",
"cpu_usage_user",
"cpu_usage_system"
],
"metrics_collection_interval": 60,
"resources": [
"*"
],
"totalcpu": false
},
"disk": {
"measurement": [
"used_percent",
"inodes_free"
],
"metrics_collection_interval": 60,
"resources": [
"*"
]
},
"diskio": {
"measurement": [
"io_time",
"write_bytes",
"read_bytes",
"writes",
"reads"
],
"metrics_collection_interval": 60,
"resources": [
"*"
]
},
"mem": {
"measurement": [
"mem_used_percent"
],
"metrics_collection_interval": 60
},
"netstat": {
"measurement": [
"tcp_established",
"tcp_time_wait"
],
"metrics_collection_interval": 60
},
"statsd": {
"metrics_aggregation_interval": 60,
"metrics_collection_interval": 10,
"service_address": ":8125"
},
"swap": {
"measurement": [
"swap_used_percent"
],
"metrics_collection_interval": 60
}
}
}
}
Are you satisfied with the above config? Note: it can be manually customized after the wizard completes to add additional items.
1. yes
2. no
default choice: [1]: 1
既にCloudWatch Log Agentが入っているかどうか。
今回は新規なのでnoの2を選択。
Do you have any existing CloudWatch Log Agent (http://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html) configuration file to import for migration?
1. yes
2. no
default choice: [2]: 2
CloudWatch Log Agentでログファイルの監視を行うか。
今回は行わないのでnoの2を選択。
Do you have any existing CloudWatch Log Agent Do you want to monitor any log files?
1. yes
2. no
default choice: [1]: 2
これまでの定義内容が「/opt/aws/amazon-cloudwatch-agent/bin/config.json」として作成完了したとのこと。
あとはそれをSSMのパラメータストアに保存するか問われるのでyesの1を選択。
Saved config file to /opt/aws/amazon-cloudwatch-agent/bin/config.json successfully.
Current config as follows:
{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "root"
},
"metrics": {
"append_dimensions": {
"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
"ImageId": "${aws:ImageId}",
"InstanceId": "${aws:InstanceId}",
"InstanceType": "${aws:InstanceType}"
},
"metrics_collected": {
"collectd": {
"metrics_aggregation_interval": 60
},
"cpu": {
"measurement": [
"cpu_usage_idle",
"cpu_usage_iowait",
"cpu_usage_user",
"cpu_usage_system"
],
"metrics_collection_interval": 60,
"resources": [
"*"
],
"totalcpu": false
},
"disk": {
"measurement": [
"used_percent",
"inodes_free"
],
"metrics_collection_interval": 60,
"resources": [
"*"
]
},
"diskio": {
"measurement": [
"io_time",
"write_bytes",
"read_bytes",
"writes",
"reads"
],
"metrics_collection_interval": 60,
"resources": [
"*"
]
},
"mem": {
"measurement": [
"mem_used_percent"
],
"metrics_collection_interval": 60
},
"netstat": {
"measurement": [
"tcp_established",
"tcp_time_wait"
],
"metrics_collection_interval": 60
},
"statsd": {
"metrics_aggregation_interval": 60,
"metrics_collection_interval": 10,
"service_address": ":8125"
},
"swap": {
"measurement": [
"swap_used_percent"
],
"metrics_collection_interval": 60
}
}
}
}
Please check the above content of the config.
The config file is also located at /opt/aws/amazon-cloudwatch-agent/bin/config.json.
Edit it manually if needed.
Do you want to store the config in the SSM parameter store?
1. yes
2. no
default choice: [1]: 1
SSMのパラメータストアに登録する名前をどうするか。
デフォルトの「AmazonCloudWatch-linux」にするためそのままエンター。
What parameter store name do you want to use to store your config? (Use 'AmazonCloudWatch-' prefix if you use our managed AWS policy) default choice: [AmazonCloudWatch-linux]
設定ファイルを保持するリージョンをどうするか。
東京リージョンのためそのままエンター。
Trying to fetch the default region based on ec2 metadata... Which region do you want to store the config in the parameter store? default choice: [ap-northeast-1]
SSMパラメータストアにデータを送信するのにアクセスキーをどうするか。
デフォルトの1を選択。
Trying to fetch the default region based on ec2 metadata...
Which AWS credential should be used to send json config to parameter store?
1. ASIAXEULPVX2IWBUONRZ(From SDK)
2. Other
default choice: [1]: 1
これでパラメータファイルについてはやっと完了です。(けっこう長かった・・・)
Successfully put config to parameter store AmazonCloudWatch-linux. Program exits now.
次にcollectdをインストールします。
※今回collectdを使用して情報採取しているのでインストールしておく必要があります。
インストールしていない状態でCloudWatchAgentを起動しようとするとエラーが出力されて起動できませんでした。
# dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm # dnf install collectd
CloudWatchエージェントを起動します。
その際、パラメータファイルとして 「/opt/aws/amazon-cloudwatch-agent/bin/config.json」を指定します。
# /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json -s
CloudWatchエージェントが起動できていることを確認して完了です。
# systemctl status amazon-cloudwatch-agent.service ● amazon-cloudwatch-agent.service - Amazon CloudWatch Agent Loaded: loaded (/etc/systemd/system/amazon-cloudwatch-agent.service; enabled; vendor preset: disabled) Active: active (running) since Thu 2022-01-06 06:36:44 UTC; 3 days ago Main PID: 743 (amazon-cloudwat) Tasks: 7 (limit: 4821) Memory: 39.6M CGroup: /system.slice/amazon-cloudwatch-agent.service mq743 /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent -config /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml -envconfig /opt/aws/amazon-cloudwatch-agent/etc/env-config.json -pidfile /opt/aws/am>
AWSコンソールのCloudWatchにカスタムメトリクスを反映するためにOSリブートします。
※リブートしないとコンソール上のCloudWatchに反映されませんでした。
# shutdown -r now
AWSコンソール上のCloudWatch ⇒すべてのメトリクス⇒ CWAgentを開くと各メトリクス種別毎にカテゴリが分かれているのが確認できます。

それぞれ詳細を見ていくとカスタムメトリクスとして取得する項目が表示されているのが確認できました。



また、グラフとしても表示できました。

以上で完了となります。
コメント