【AWS】AutoScalingで作成したEC2にCloudWatchAgentをインストールしてメトリクスを集約してみた

AWS

「AutoScalingで作成したEC2にCloudWatchAgentをインストールしてメトリクスを集約する手順を知りたい」「”aggregation_dimensions”でメトリクスを集約したがCloudWatchのメトリクスがうまく収集できないので解決策を知りたい」「CloudWatchに表示されないので解決策を知りたい」

このような疑問に対し、筆者がハンズオンで検証した手順をご紹介します。また、ハマった点と解決した方法もご紹介します。

もっとより良い手順や誤りなどありましたが、お手数ですが、お問い合せかTwitterのDMいただけますと幸いです。すぐに修正いたします!

>> お問い合せ
>> Twitter

同じ部分でハマった方は、調査時間を1/4くらい短縮できると思いますよ!


  • このハンズオンで目指す構成
  • このハンズオン作業のゴール
  • 筆者の環境
  • 筆者が検証したハンズオンの手順
  • 筆者がつまずいた箇所
  • まとめ

このハンズオンで目指す構成

以下のような構成を目指します。

まず、構成図のtest-public-subnet-aにAuto Scaling gropを作成し、EC2(test-web-asg)を起動します。
次に、EC2にCloudWatchAgentをインストールし、メトリクスを集約してCloudWatchに転送するまでをご紹介します。

この構成の背景

この構成の背景は以下となります。

  1. AutoScalingで作成したEC2にCloudWatch Agentをインストールし、カスタムメトリクス(ディスク・メモリ・CPU利用率)を集約して取得したい
  2. 集約方法は ”aggregation_dimensions”: [[“AutoScalingGroupName”]], の設定で対応する
  3. AutoScalingGroupNameで集約したメトリクスをCloudWatchで見たい
  4. 上記を利用してアラームを作成したい

その1について
Webサーバーのように、不可に応じてAutoScalingが起動し、インスタンスがスケールイン・スケールアウトを繰り返す環境では、EC2のインスタンスIDが入れ替わるため、アラームを作成してインスタンスを監視する場合は、メトリクスを集約するなどの工夫が必要です。


その2について
集約する方法としては、CloudWatchの設定ファイルに “aggregation_dimensions” を記載して、集約するのが一番手軽なので、検証してみることにしました。

他の方法として、Lambdaに関数を書いてスケールイン・スケールアウトのたびに能動的にアラームを書き替えることもできそうでしたが、実装の手軽さの点で ”aggregation_dimensions” の方が優位と感じ、今回は見送りました。


その3について
CloudWatchのメトリクスで確認することが可能です。


その4について
インスタンスIDが変わってもAutoScalingグループでアラームを作成しているため、問題ありません。


このハンズオン作業のゴール

構成図の赤枠で囲んだ箇所を中心にご紹介します。作業のベースとなるVPCを作ったり、EC2をたてたりする部分は他の記事で対応していますので、リンクを貼っておきます。

関連記事

>> AWSでシングル構成でワードプレスのブログサービスを構築する手順の概要/step01 VPCを作成する
>> AWSでシングル構成でワードプレスのブログサービスを構築する手順の概要/step02 サブネットを作成する
>> AWSでシングル構成でワードプレスのブログサービスを構築する手順の概要/step03 インターネットゲートウェイを作成する
>> AWSでシングル構成でワードプレスのブログサービスを構築する手順の概要/step05 EC2を作成する
>> step05 ELBを作成する

筆者の環境

ローカル開発環境 Windows10からブラウザよりAWSマネジメントコンソールに接続して作業
EC2のOS Amazon Linux 2
SSH通信 TeraTermを利用
作図 dwarioのAWS19アイコンを利用

AutoScalingで作成したEC2にCloudWatchAgentをインストールしてメトリクスを集約する手順の概要

  • Step 01 IAMロールを作成
  • Step 02 起動テンプレートを作成
  • Step 03 AutoScalingグループを作成
  • Step 04 AutoScalingグループで起動したEC2にCloudWatchAgentをインストールする
  • Step 05 CloudWatchAgentを起動する
  • Step 06 CloudWatchAgentのステータスとログを確認
  • Step 07 VPCのダッシュボードにて、上記サイトへのエンドポイントを作成
  • Step 08 再度、CloudWatchAgentのログを確認し、問題なく起動していることを確認
  • Step 09 CloudWatch > メトリクス > CWAgent > AutoScalingGroupNameでメトリクスが取得できていることを確認

Step 01 IAMロールを作成

以下の参考URLを参考にCloudWatch エージェントで使用する IAM ロールを作成します。今回はロールのみの作成でOKです。

参考URL

>> 【公式】CloudWatch エージェントで使用する IAM ロールおよびユーザーを作成する

CloudWatch エージェントで使用する IAM ロールを作成

> AWS マネジメントコンソール にサインイン
> IAM コンソールを開く
> ナビゲーションペインで [ロール] を選択した後、[ロールの作成] を選択
> [信頼されたエンティティの種類を選択] で、[AWS のサービス] を選択
> [Common use cases (一般的ユースケース)] で [EC2 (EC2)] を選択し、[Next: Permissions (次へ: アクセス許可)] を選択
> ポリシーのリストで以下を選択し、「次へ」をクリック
  • CloudWatchAgentServerPolicy
  • CloudWatchAgentAdminPolicy

注意点

※ 横にあるチェックボックスを選択する。
※ 必要に応じて、検索ボックスを使用してポリシーを見つける。
※ 他のブログ記事などで、Systems Manager を使用して CloudWatch エージェントをインストールまたは設定するため、[AmazonSSMManagedInstanceCore] を選択するよう紹介しているものもあるが、本記事ではコマンドラインのみ使用してエージェントを開始および設定する場合、このポリシーは不要。
> つづいて、[次へ: タグ] を選択して以下を記載
・タグ Name test-CWAgent-role
> [次へ: 確認] を選択
> つづいて、以下を記載し、[ロールの作成] を選択
・[ロール名] に、新しいロールの名前 (今回はtest-CWAgent-role)

Step 02 起動テンプレートを作成

以下のURLを参考に起動テンプレートを作成します。作成時のポイントは以下です。

・事前にAMI(AmazonMachineイメージを準備する)。なければ、EC2をたてて、AMIを作成しましょう。
>> AWSでシングル構成でワードプレスのブログサービスを構築する手順の概要/step05 EC2を作成する
・[Advanced details (高度な詳細)]の[IAM インスタンスプロファイル]で先ほど作成したCloudwatchエージェントを操作するためのIAMロール(今回はtest-CWAgent-role)を選択しておきましょう。

参考URL

>> Auto Scaling グループの起動テンプレートの作成

注意点

起動設定からオートスケーリンググループを起動することもできますが、起動設定はバージョンン管理ができないため、起動テンプレートからオートスケーリンググループを作成することをおススメします。

Step 03 AutoScalingグループを作成

以下の公式記事を参考に、先ほどの作業で作成した起動テンプレートを活用して、AutoScalingグループを作成しましょう。

今回作成したAutoScalingグループの設定

[Auto Scalingグループ名] test-web-asg
[起動テンプレート]  上記で作成した起動テンプレート (今回はlaunch-template-01)
[Launch template version 0.0.1

参考URL

>> 起動テンプレートを使用した Auto Scaling グループの作成

Step 04 AutoScalingグループで起動したEC2にCloudWatchAgentをインストールする

AutoScalingグループを作成するとEC2が起動されます。起動したEC2にCloudwatchAgentをインストールします。

参考URL

>> コマンドラインを使用して CloudWatch エージェントをダウンロードおよび設定する
>> CloudWatch エージェント設定ファイルを手動で作成または編集する

インストールのポイント

インストールの際は設定ファイルをウィザードを使うか、手動かで作成する必要があります。筆者は手動の方が取得するメトリクスをシンプルで分かりやすく設定できる感じたので、こちらをご紹介します。また、パラメーターを利用して管理する方法は割愛します。

手順

> CloudWatchCloudWatch エージェントパッケージをインストール
sudo yum install amazon-cloudwatch-agent
> 設定ファイルを作成する
cd /opt/aws/amazon-cloudwatch-agent/bin/
sudo touch config.json
sudo vi config.json

注意点

・設定ファイルの格納先はAmazonでは以下を推奨しているようです。このあたりは、いろいろとおためしください。
/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
・設定ファイルはjsonで記載されます。jsonの構文チェックは以下のサイトが便利です。

>> JSON整形&構文チェック


“aggregation_dimensions”の設定例

設定項目

実行アカウント root
aggregation_dimensions” “AutoScalingGroupName”
主なメトリクス ・disk/used_percent/取得サイクル 60秒おき
・メモリ/mem_used_percent/取得サイクル 60秒おき
・CPU/cpu_usage_use/取得サイクル 60秒おき

設定ファイル

{
"agent": {
"metrics_collection_interval": 60,
"run_as_user": "root"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/messages",
"log_group_name": "messages",
"log_stream_name": "{instance_id}"
}
]
}
}
},
"metrics": {
"append_dimensions": {
"AutoScalingGroupName": "${aws:AutoScalingGroupName}",
"ImageId": "${aws:ImageId}",
"InstanceId": "${aws:InstanceId}",
"InstanceType": "${aws:InstanceType}"
},
"aggregation_dimensions": [
[
"AutoScalingGroupName"
]
],
"metrics_collected": {
"disk": {
"measurement": [
"used_percent"
],
"metrics_collection_interval": 60,
"resources": [
"*"
]
},
"mem": {
"measurement": [
"mem_used_percent"
],
"metrics_collection_interval": 60
},
"statsd": {
"metrics_aggregation_interval": 60,
"metrics_collection_interval": 10,
"service_address": ":8125"
},
"cpu": {
"measurement": [
"cpu_usage_user"
],
"metrics_collection_interval": 60,
"resources": [
"*"
],
"totalcpu": false
}
}
}
}

Step 05 CloudWatchAgentを起動する

つづいて、CloudWatchAgentを起動していきましょう。

参考URL

>> コマンドラインを使用して CloudWatch エージェントを起動する

手順

> CloudWatch エージェントを開始する
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json
>> ステータスを確認する
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status

つづいて、AWSマネジメントコンソールでCloudWatchを確認していきます。

> クラウドウォッチメトリクスで収集できているか確認する
> AWSマネジメントコンソール
> CloudWatch
> ダッシュボード
> メトリクス
> すべてのメトリクス
> CWAgent
> AutoScalingGropuName
> 先ほど設定したメトリクス名(今回はdisk_used_percent・cpu_usage_user・mem_used_percent)が取得できていればOK 図A mem_user_percentの表示例

図A mem_user_percentの表示例

> つづいて、インスタンスを再起動してみて、再度チェックし問題なければOKです。
sudo reboot

Step 06 CloudWatchAgentのステータスとログを確認

筆者はStep 05まではかなりスムーズに検証することができましたが、このあとドはまりしました。ハマった内容はちゃんと設定しはたずなのに、CloudWatchAgentでメトリクスが収集されないというものでした。

で、いろいろと調べた結果、こちらの記事を参考にさせていただきました。
>> 【クラスメソッド】CloudWatch Agentでちょっとハマった話

というわけで、Step 05までうまく来てるということは、EC2からインターネットへの接続、CloudWatchAgentのインストールはうまくいっていると推測されますので、いったんCloudWatchAgentのステータスを見てみましょう。

手順

> ステータス確認コマンド
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status
$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status
{
"status": "running",
"starttime": "2021-03-20T10:33:48+0000",
"version": "1.247345.35"
}
$

上記の結果で、statusがrunningとなっていればCloudwatchは起動してます。

> つづいて、CloudWatchAgentのログを確認してみましょう。
> ログ確認コマンド

ログ確認コマンドの実行結果

tail -f /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log

2021/03/20 09:23:32 I! Config has been translated into TOML /opt/aws/amazon-cloudwatch-agent/etc /amazon-cloudwatch-agent.toml
2021/03/20 09:23:32 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-c loudwatch-agent.json ...
2021/03/20 09:23:32 Reading json config file path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-c loudwatch-agent.d/file_config.json ...
2021/03/20 09:23:32 I! Detected runAsUser: root
2021/03/20 09:23:32 I! Change ownership to root:root
2021-03-20T09:23:32Z I! Starting AmazonCloudWatchAgent 1.247345.35
2021-03-20T09:23:32Z I! Loaded inputs: disk logfile mem statsd cpu
2021-03-20T09:23:32Z I! Loaded aggregators:
2021-03-20T09:23:32Z I! Loaded processors: ec2tagger
2021-03-20T09:23:32Z I! Loaded outputs: cloudwatch cloudwatchlogs
2021-03-20T09:23:32Z I! Tags enabled: host=ip-172-16-1-123.ap-northeast-1.compute.internal
2021-03-20T09:23:32Z I! [agent] Config: Interval:1m0s, Quiet:false, Hostname:"ip-172-16-1-123.ap -northeast-1.compute.internal", Flush Interval:1s
2021-03-20T09:23:32Z I! [logagent] starting
2021-03-20T09:23:32Z I! [logagent] found plugin cloudwatchlogs is a log backend
2021-03-20T09:23:32Z I! [logagent] found plugin logfile is a log collection
2021-03-20T09:23:32Z I! [processors.ec2tagger] ec2tagger: EC2 tagger has started initialization.
2021-03-20T09:23:32Z I! cloudwatch: get unique roll up list [[AutoScalingGroupName]]
2021-03-20T09:23:32Z I! Started the statsd service on :8125
2021-03-20T09:23:32Z I! cloudwatch: publish with ForceFlushInterval: 1m0s, Publish Jitter: 37s
2021-03-20T09:23:32Z I! Statsd listener listening on: [::]:8125
2021-03-20T09:23:33Z I! [logagent] piping log from messages/i-01614e0a272a99480(/var/log/message s) to cloudwatchlogs
2021-03-20T09:25:32Z W! [processors.ec2tagger] ec2tagger: Unable to describe ec2 tags for initia l retrieval: RequestError: send request failed
caused by: Post https://ec2.ap-northeast-1.amazonaws.com/: dial tcp 54.239.96.159:443: i/o timeo

こんな感じで問題なく起動したかに見えていましたが、https://ec2.ap-northeast-1.amazonaws.com/ への接続がタイムアウトしていました。さらに確認していくと、タイムアウトした接続先は以下でした。

タイムアウトしていたサイト

com.amazonaws.ap-northeast-1.monitoring
com.amazonaws.ap-northeast-1.ec2
com.amazonaws.ap-northeast-1.logs

そこで、以下の記事を参考にそれぞれのサイトへのエンドポイントをVPCに作成しました。

エンドポイントを作成する際に参考にしたサイト

>> 【公式】インターフェイス VPC エンドポイント (AWS PrivateLink)


Step 07 の参考URL

CloudWatcエージェントが開始されない場合
>> CloudWatch エージェントのトラブルシューティング

Step 07 VPCのダッシュボードにて、上記サイトへのエンドポイントを作成

参考URL

こちらの記事を参考にVPCにエンドポイントを作成することで、無事クラウドWatchにメトリクスをプッシュ可能になりました。図A
>> 【公式】インターフェイス VPC エンドポイント (AWS PrivateLink)

図A

Step 08 再度、CloudWatchAgentのログを確認し、問題なく起動していることを確認

手順

> 再度、CloudWatchAgentのログを確認してみましょう。
> ログ確認コマンド
tail -f /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log

エラーがなければ問題なしですね。

Step 09 CloudWatch > メトリクス > CWAgent > AutoScalingGroupNameでメトリクスが取得できていることを確認

手順

> クラウドウォッチメトリクスで収集できているか確認する
> AWSマネジメントコンソール
> CloudWatch
> ダッシュボード
> メトリクス
> すべてのメトリクス
> CWAgent
> AutoScalingGropuName
> 先ほど設定したメトリクス名(今回はdisk_used_percent・cpu_usage_user・mem_used_percent)が取得できていればOK 図A mem_user_percentの表示例

図A mem_user_percentの表示例

筆者がつまずいた箇所

その1

OKだった設定順 筆者の環境ですと、AutoScalingGropを作成 → EC2を起動 → CloudWatchAgentをインストール の順で設定をしないとメトリクスがうまく集約されませんでした。
NGだった設定順 EC2を起動する → CloudWatchAgentをインストール → メトリクスが集約されない

このあたりはも少し検証を進めて整理したいですね。もしメトリクスが集約されない場合は、設定順を見直すといいかもです。

その2

設定をしたにもかかわらずCloudwatchでメトリクスが見れない場合は、ログを確認してエラーがないか確認してみてもいいかもです。筆者はログをみてエンドポイントの追加が必要であることをつきとめました。

やはり、トラブル切り分けの切り札はログの確認なんですね。。

まとめ

本記事では、「AutoScalingで作成したEC2にCloudWatchAgentをインストールしてメトリクスを集約する手順を知りたい」「”aggregation_dimensions”でメトリクスを集約したがCloudWatchのメトリクスがうまく収集できないので解決策を知りたい」「CloudWatchに表示されないので解決策を知りたい」このような疑問に対し、筆者が検証した手順をご紹介しました。

以上、本記事がお役に立てば幸いです。