【AWS】王道なインフラ構成でWordpressをデプロイ、運用する Part2 〜サーバ監視〜

#はじめに

前回ワードプレスをデプロイしました。今度はAWSを設定してEC2インスタンスの監視機能を実装していきたと思います。

今回の完成イメージはこんな感じ。

![王道インフラ構築.008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837136/1cbe183c-3293-7946-00e4-b5800eeee3bd.png)


EC2インスタンスにCloudWatchAgentをインストールして、EC2の情報をCloud Watchにアップロードし、CloudWatchダッシュボードに表示させる。

これができれば、あとはアラームを設定したりすれば、EC2インスタンスの監視を自動化できます。

# 1. IAMロールの設定

以下のポリシーをもったIAMロールを作成し、EC2インスタンスにアタッチします。

・CloudWatchAgentAdminPolicy
・AmazonEC2RoleforSSM

IAMロールを作成します。作成の確認画面はこんな感じ。

![スクリーンショット 2021-08-01 17.59.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837136/48e4c5d1-d2d5-c169-71f6-ceb1a35e08ad.png)

そしたら作成したIAMロールをEC2インスタンスにアタッチしましょう。

# 2. CloudWatchAgent をインストール

そしたらEC2インスタンスにSSHでログインして、CloudWatchAgentをインストールしていきましょう。

```
#CloudWatchAgentのインストール
$ sudo yum install amazon-cloudwatch-agent -y
```

またcollectdが必要なのでインストールします。

```
#collectdのインストールに必要なパッケージのインストール
$ sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm -y

#collectdのインストール
$ sudo yum -y install collectd -y
```

# 3. CloudWatchAgentの初期設定

そしたらCloudWatchAgentのインストールウィザードを起動します。これを起動すると、対話形式でCloud WatchAgentのインストール設定をすることができます。

```
$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
```

こんな感じに設定しました。

```
=============================================================
= Welcome to the AWS CloudWatch Agent Configuration Manager =
=============================================================
On which OS are you planning to use the agent?
1. linux
2. windows
3. darwin
default choice: [1]:
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
Which user are you planning to run the agent?
1. root
2. cwagent
3. others
default choice: [1]:
1
Do you want to turn on StatsD daemon?
1. yes
2. no
default choice: [1]:
1
Which port do you want StatsD daemon to listen to?
default choice: [8125]
8125
What is the collect interval for StatsD daemon?
1. 10s
2. 30s
3. 60s
default choice: [1]:
3
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
Do you want to monitor metrics from CollectD?
1. yes
2. no
default choice: [1]:
1
Do you want to monitor any host metrics? e.g. CPU, memory, etc.
1. yes
2. no
default choice: [1]:
1
Do you want to monitor cpu metrics per core? Additional CloudWatch charges may apply.
1. yes
2. no
default choice: [1]:
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
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
Which default metrics config do you want?
1. Basic
2. Standard
3. Advanced
4. None
default choice: [1]:
2
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"
				],
				"metrics_collection_interval": 60,
				"resources": [
					"*"
				]
			},
			"mem": {
				"measurement": [
					"mem_used_percent"
				],
				"metrics_collection_interval": 60
			},
			"statsd": {
				"metrics_aggregation_interval": 60,
				"metrics_collection_interval": 60,
				"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
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
Do you want to monitor any log files?
1. yes
2. no
default choice: [1]:
1
Log file path:
/var/log/messages
Log group name:
default choice: [messages]
qii-messages
Log stream name:
default choice: [{instance_id}]

Do you want to specify any additional log files to monitor?
1. yes
2. no
default choice: [1]:
2
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"
	},
	"logs": {
		"logs_collected": {
			"files": {
				"collect_list": [
					{
						"file_path": "/var/log/messages",
						"log_group_name": "qii-messages",
						"log_stream_name": "{instance_id}"
					}
				]
			}
		}
	},
	"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"
				],
				"metrics_collection_interval": 60,
				"resources": [
					"*"
				]
			},
			"mem": {
				"measurement": [
					"mem_used_percent"
				],
				"metrics_collection_interval": 60
			},
			"statsd": {
				"metrics_aggregation_interval": 60,
				"metrics_collection_interval": 60,
				"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
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]
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]
ap-northeast-1
Which AWS credential should be used to send json config to parameter store?
1. ASIA4T3UULSTI3QK7OO7(From SDK)
2. Other
default choice: [1]:
1
Successfully put config to parameter store AmazonCloudWatch-linux.
Program exits now.
```

## 4. CloudWatchAgentを起動する

そしたらCloudWatchAgentを起動します。

```
#自動起動設定と起動
$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c ssm:AmazonCloudWatch-linux -s

#ステータス確認
$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a status -m ec2
```

これで、CPU使用率、メモリ使用率、ディスク使用率、ログの情報をCloudWatchに送信してくれます。

## 5. プロセスの情報を取得する

プロセスの情報を取得するには、AWS Systems Managerを使って、CloudWatchAgentのconfigファイルを修正する必要があります。

Systems Managerのサービスを開き、左ペインのパラメータストアを開きます。

CloudWatchAgentのインストールウィザードで僕と同じように設定していれば、「AmazonCloudWatch-linux」というファイルがあるはずです。ここに記載されている内容に沿って、CloudWatchAgentはCloudWatchに情報を送信します。

編集を押して、現在の値を全て削除した後、以下の設定ファイルの内容をそのままコピペします。

```json
{
	"agent": {
		"metrics_collection_interval": 60,
		"run_as_user": "root"
	},
	"logs": {
		"logs_collected": {
			"files": {
				"collect_list": [
					{
						"file_path": "/var/log/messages",
						"log_group_name": "kok-messages",
						"log_stream_name": "{instance_id}"
					}
				]
			}
		}
	},
	"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"
				],
				"metrics_collection_interval": 60,
				"resources": [
					"*"
				]
			},
			"mem": {
				"measurement": [
					"mem_used_percent"
				],
				"metrics_collection_interval": 60
			},
			"statsd": {
				"metrics_aggregation_interval": 60,
				"metrics_collection_interval": 60,
				"service_address": ":8125"
			},
			"swap": {
				"measurement": [
					"swap_used_percent"
				],
				"metrics_collection_interval": 60
			},
      "procstat": [
        {
            "exe": "nginx",
            "measurement": [
                "cpu_time",
                "cpu_time_system",
                "cpu_time_user",
                "pid_count"
            ]
        },
        {
            "exe": "collectd",
            "measurement": [
                "cpu_time",
                "cpu_time_system",
                "cpu_time_user",
                "pid_count"
            ]
            }
        ]
		}
	}
}
```

"procstat"以下で情報を送信するプロセスを記載しています。今回は「nginx」「collectd」という文字列が含まれるプロセスの情報を送信するように設定しています。

変更を保存したら、左ペインから「Run Command」を選択します。Run Commandを使って今回の変更を反映させます。

右上の「Run Command」を押したら、以下のようにコマンド実行の設定をします。

![スクリーンショット 2021-08-01 18.31.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837136/d79e9ff2-d6df-e654-f048-60575e18b7cb.png)

![スクリーンショット 2021-08-01 18.37.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837136/403bb296-9c87-fe71-4a1d-69c4f2eec0eb.png)

![スクリーンショット 2021-08-01 18.35.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837136/278c80ae-d58c-fe5e-2f1f-075822be74f6.png)

これでコマンドを実行します。
コマンド実行が成功したことを確認します。

![スクリーンショット 2021-08-01 18.38.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837136/99bfb88f-40ab-b7c1-2dd4-a2c74a88855b.png)

そしたらEC2インスタンスに戻って設定変更が反映しているかどうかみてみましょう。

```
$ cat /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/ssm_AmazonCloudWatch-linux
```

先ほどパラメータストアで変更した内容が記載されているはずです。

そしたらもう一度CloudWatchAgentを起動します。

```
#自動起動設定と起動
$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c ssm:AmazonCloudWatch-linux -s

#ステータス確認
$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a status -m ec2
```
これでプロセスの情報もCloudWatchに送信されます。

# 6. CloudWatchダッシュボードの設定

あとはCloudWatchサービスを開いて、ダッシュボードを設定するだけです。
お好きな情報をダッシュボードに追加してください

ダッシュボードはこんな感じに設定してみました。

![スクリーンショット 2021-08-01 18.49.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837136/db05676b-073a-1949-3d91-1f3bcefe23c1.png)

# 7. CloudWatchアラームの設定

アラームも設定していきます。

・CPU空き領域が20%以下になったら発報
・メモリ使用率が80%を超えたら発報
・ディスク使用率が80%を超えたら発報
・nginxのプロセス数が0だったら発報

こんな感じに設定してみました。

![スクリーンショット 2021-08-01 18.55.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837136/2c2c6c21-a7a3-2fca-91fc-e03789b0f8c1.png)

これで基本的な監視設定はできました！

またAWSであれば、このデータをもとにメモリ使用率が頻繁に80%を超えるのであればサーバーを自動で増やすなんて設定もできちゃうので便利ですよね。

そんな感じの便利な設定もこれから実装できればと思います。

それでは、どうぞよしなに