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

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

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

まず、構成図のtest-public-subnet-aにAuto Scaling groupを作成し、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をたてたりする部分は他の記事で対応。リンクは以下。

関連記事

step01 VPCを作成する
step02 サブネットを作成する
step03 インターネットゲートウェイを作成する
step05 EC2を作成する
step06 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を作成。
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を起動する

参考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でちょっとハマった話

※CloudWatch Agentを使用して、CloudWatch Logsへのログを送信する際は、com.amazonaws.ap-northeast-1.logsエンドポイントも必要になるので注意。

というわけで、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でメトリクスが見れない場合は、ログを確認してエラーがないか確認してみてもいいかも。ログをみてエンドポイントの追加が必要であることが発覚。やはり、トラブル切り分けの切り札はログの確認ということで。。