Amazon CloudWatchでEC2上のプロセス死活監視と自動復旧する方法(インスタンス自体の再起動なし)

## はじめに
オンプレからクラウドへリフト&シフト案件にて、
既存の監視ツールをそのまま移行している経験はありませんか。
OSレイヤーより上の監視を行う際はサードパーティの監視ツールをそのまま使用するケースがあるかと思います。
そういった監視サービスは便利な反面ライセンス管理・更新の手間/コストがかかるため極力導入を控えたいといった課題がある中、
本記事ではOSレイヤーより上の**プロセス監視**をAWSの機能を組み合わせて実現させた記事になります。

## 結論
以下サービスの組み合わせでプロセス死活監視/自動復旧が実現可能でした。
※ただし、自動復旧のための再起動シェルは作成が必要です。

### 組み合わせたサービス
【死活監視検知/メール連絡】
「CloudWatchアラーム」⇒「SNS」

【死活監視検知/自動復旧】
「CloudWatchアラーム」⇒「EventBritge」⇒「SSM RunCommand」
※RunCommandで実行させるシェルは別途作成

### CloudWatchで収集できるプロセス監視観点
今回は「procstat」というプラグインを使用して、
プロセス情報収集/メトリクス検出できるようにします。
procstatプラグインを使用して収集できるプロセス情報は以下の通りです。

#### 収集可能な情報
【使用しそうな主要情報】
・pid_count(プロセスID の数)
　　※正常動作中なら1、停止中なら0となり死活監視に使用
・cpu_time(プロセスで CPU を使用する時間)
・memory_data(プロセスで使用するメモリの量)

【その他取得可能な情報全量】
[procstat プラグインでプロセスメトリクスを収集する](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-procstat-process-metrics.html)


## 実装してみた
■構成図
【死活監視検知/メール連絡】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/6f5b98f5-df4e-5562-5969-11fd9eddadf3.png)


【死活監視検知/自動復旧】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/3d61d4d0-15e3-401a-785e-cc8dd756fe47.png)


### 1.【死活監視検知/メール連絡】の実装
<前提>
・使用OS：AmazonLinux2
・EC2の構築手順は割愛
・EC2に対し以下IAMロールが付与されている
　　・CloudWatchAgentServerPolicy(CloudWatchエージェントとの通信用)
　　・CloudWatchAgentAdminPolicy(CloudWatchエージェントとの通信用)
　　・AmazonSSMManagedInstanceCore(セッションマネージャ接続用)
　　　参考元：[CloudWatch エージェントで使用する IAM ロールとユーザーを作成する](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-iam-roles-for-cloudwatch-agent.html)

#### 1-1.CloudWatch Agentの導入
※AmazonLinux2であればインスタンス内にAgent用パッケージが存在しているが、今回は汎用的に使用できるRunCommandで導入

①AWSコンソールより「Systems maneger」⇒「RunCommand」

②パラメータとして以下入力
・コマンドドキュメント：AWS-ConfigureAWSPackage
・Action：install
・Installation Type：Uninstall and reinstall
・Name：AmazonCloudWatchAgent
・Version：latest
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/4133e8f4-2621-0da0-f1eb-7b807267cf06.png)

#### 1-2.CloudWatch Agentの設定(プロセス/その他メトリクス・ログ取得)
③AWSコンソールより「Systems maneger」⇒「ParameterStore」
※CloudWatch エージェント設定を実施

④以下jsonファイルを値としてパラメータを設定
・名前：AmazonCloudWatch-linux-config
・タイプ：文字列
・データ型：text
・値：以下jsonファイル

<Cloudwatchエージェントからの検知対象>
採取する対象メトリクス：
　・cpu
　　→CPU がアイドル状態の時間の割合(%)
　　→CPU が I/O 操作の完了を待機している時間の割合(%)
　　※CPUは標準メトリクスである程度の情報は確認できるため、不要としてもよい
　・disk
　　→ディスクスペース合計に対する使用済みの割合(%)
　　※ディスクは標準メトリクスである程度の情報は確認できるため、不要としてもよい
　・メモリ
　　→現在使用中のメモリの割合(%)
　・**プロセス**
　　→「プロセス名：httpd」として起動中のプロセス数(カウント)

　※採取する対象OSログ：
　　OSログとして出力される「messageログ」「auditログ」をCloudwatchLogsへ転送設定

　　<参照資料>
　　　設定手順：[CloudWatch エージェント設定ファイルを手動で作成または編集する](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html#CloudWatch-Agent-Configuration-File-Logssection)
　　　採取対象メトリクス一覧：[Linux および macOS インスタンスで CloudWatch エージェントにより収集されるメトリクス](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/metrics-collected-by-CloudWatch-agent.html#linux-metrics-enabled-by-CloudWatch-agent)
　　　procstatについて：[procstat 向けの CloudWatch エージェントの設定](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-procstat-process-metrics.html#CloudWatch-Agent-procstat-configuration)

```json
{
  "metrics": {
    "namespace": "CWAgent-test",
    "append_dimensions": {
      "ImageId": "${aws:ImageId}",
      "InstanceId": "${aws:InstanceId}",
      "InstanceType": "${aws:InstanceType}",
      "AutoScalingGroupName": "${aws:AutoScalingGroupName}"
    },
    "metrics_collected": {
      "cpu": {
        "resources": ["*"],
        "measurement": ["cpu_usage_idle", "cpu_usage_iowait"],
        "metrics_collection_interval": 60
      },
      "disk": {
        "measurement": ["used_percent"],
        "metrics_collection_interval": 60
      },
      "mem": {
        "measurement": ["mem_used_percent"],
        "metrics_collection_interval": 60
      },
      "procstat": [
        {
          "exe": "httpd",
          "measurement": ["pid_count"],
          "metrics_collection_interval": 60
        }
      ]
    }
  },
  "logs": {
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/var/log/audit/audit.log",
            "log_group_name": "audit",
            "log_stream_name": "{ip_address}"
          },
          {
            "file_path": "/var/log/messages",
            "log_group_name": "messages",
            "log_stream_name": "{instance_id}"
          }
        ]
      }
    }
  }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/804345e0-27ee-b876-5f2f-9e6b8cd5572a.png)

⑤AWSコンソールより「Systems maneger」⇒「RunCommand」

⑥ ④で作成したパラメータをインプットに実行
・コマンドドキュメント：AmazonCloudWatch-ManageAgent
・Action：configure
・Mode：ec2
・Optional Configuration Lovation：AmazonCloudWatch-linux-config(④で作成したパラメータ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/0acb0195-d7fb-c9e8-b966-ecc13924852d.png)
※設定を行ったメトリクスが取得できたことを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/913008d5-b660-302d-7879-90e2d6472e5f.png)

#### 1-3.メール通知用SNS作成
①AWSコンソールより「SNS」⇒「トピック」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/6c570db9-e99a-71f9-5e21-68de7d3b60a4.png)

② ①で作成したトピックに紐づくサブスクリプション作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/f4d3c303-396d-43cf-688d-de1498335f05.png)

#### 1-4.CloudWatch Alermの作成

①AWSコンソールより「Cloud Watch」⇒「アラーム」⇒「1-2.CloudWatch Agentの設定にて採取対象としてプロセス用メトリクスを選択」

②メトリクス検知条件を設定
条件：「1より低い」を設定
　→0であればプロセスダウンを意味し、死活監視として検知設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/44a3e264-bf67-a70b-7748-7d7f35d411bd.png)

③「1-3.メール通知用SNS作成」にて作成したSNSをトリガーとして設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/8502bc5d-8bce-3e22-4700-d0c0d881f804.png)

③以下アラーム名を設定
アラーム名：Cloudwatch-Process-Alarm
※本アラーム名はEventBritgeの検出条件に使用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/6c9b2904-a3ab-fe5a-90b5-6ad36d3846c0.png)

### 2.【死活監視検知/自動復旧】の実装
※「1.【死活監視検知/メール連絡】の実装」が完了している前提とします。
　また、メール通知が不要な場合は、「1-3.メール通知用SNS作成」をスキップして、
　Cloudwatchアラームのトリガーとして設定しなければOKです。

#### 2-1.EventBritge設定
①AWSコンソールより「EventBritge」⇒「ルール」⇒「ルールを作成」

②イベントパターンを以下設定値の通り設定
・作成のメソッド：カスタムパターン
・イベントパターン：以下jsonファイル参照

<設定したイベントパターン>
「アラーム名：Cloudwatch-Process-Alarm」にてステータスが「OK」から[ALARM]に変更されたときに検知できるよう設定
イベントパターンに使用できるイベントは[サポートされているサービスからの CloudWatch Events イベントの例](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/EventTypes.html#cloudwatch-event-type)を参照

```json
{
  "source": ["aws.cloudwatch"],
  "detail-type": ["CloudWatch Alarm State Change"],
  "detail": {
    "alarmName": ["Cloudwatch-Process-Alarm"],
    "state": {
      "value": ["ALARM"]
    }
  }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/ed3c471a-409c-674a-a637-f8f2c24facae.png)

③ターゲットを以下設定値の通り設定
・ターゲットタイプ：AWSのサービス
・ターゲットを選択：System Manager 実行コマンド(RunCommandのこと)
・ドキュメント：AWS-RunShellScript
・ターゲットキー：InstanceIds(タグをターゲットとする設定も可)
・ターゲット値：i-0daf1e81fa39ce4ab(ターゲットとなるインスタンスID)
・Commands：★ここでプロセスに沿った再起動シェルを入力★
　※今回は「httpd」を想定している
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/fa8834da-1488-3fea-d7c4-1328ee82c8f2.png)!

#### 2-2.検証
①現在のステータスが「OK」であることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/b8aa50f1-e268-560d-3de4-e982714db42c.png)

②プロセスを止め、ステータスが「Alarm」となったことを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/e9e6b289-f314-c6a6-2c51-4690617c6d99.png)

③ステータス検知のSNSが登録したアドレスに届いたことを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/33f4034b-1b3a-418f-658b-7d118f1b1d08.png)

④ステータスが「EventBritge」がトリガーされプロセス起動コマンドが実行されたことを確認
　※RunCommandから実施成功履歴を確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/1dc0fee0-a7d2-f301-461c-082fc1f10816.png)

⑤プロセスが自動的に再起動され、現在のステータスが「OK」となったことを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1764568/33a76224-171b-21d1-6060-cc3636a17da9.png)


### その他補足事項
・エージェント導入サーバの以下ファイルディレクトリ配下に、適用中のエージェント設定ファイルが格納されている。
　/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d

### 終わりに
今回はAWSサービスだけでプロセス監視の実現をしてみました。
システムとしてプロセス監視の導入を検討している方の参考になれば幸いです。