OPS

amazon-cloudwatch-setup

Amazon CloudWatchエージェントのセットアップ方法(Linux)

2023.02.09

本記事のポイント

Amazon CloudWatch(以下、CloudWatch)エージェントのセットアップ方法から基本的なアラーム設定までのやり方を紹介いたします。
はじめてCloudWatchエージェントをセットアップする際につまずきやすいポイントについての解説もしますので、ぜひ最後まで御覧ください。


はじめに

サーバーの監視にCloudWatchを利用する企業様も多いと思います。そこで今回はプロセスやログの監視を実装するためのCloudWatchエージェントのセットアップ方法について初めての方にも分かりやすいようご説明させていただきます。

今回のセットアップ環境
– OS:Amazon Linux 2
– アーキテクチャ:x86-64

EC2用のIAMロール作成と割当

CloudWatchを利用するに当たってEC2に “cloudwatch:PutMetricData”の権限が付与されている必要があります。”cloudwatch:PutMetricData”の権限を持つポリシーとしては以下の2つがあります。

  • CloudWatchAgentServerPolicy
  • CloudWatchAgentAdminPolicy
  • 主な違いとしてはSSMのパラメータストアに対する書き込み権限である”ssm:PutParameter”の有無です。
    左:CloudWatchAgentServerPolicy
    右:CloudWatchAgentAdminPolicy

    Amazon CloudWatch パラメータストア

    Systems Managerとパラメータストアを活用することで一度に複数のサーバーに対してCloudWatchエージェントのセットアップを行うことができます。今回はパラメータストアの活用を想定してセットアップを進めますので”cloudwatch:PutMetricData”と”ssm:PutParameter”の権限を持つ「CloudWatchAgentAdminPolicy」を付与したIAMロールを作成しEC2に割り当てましょう。

    今回は以下のIAMロールを作成・付与しましたが、既にEC2へ割り当てているIAMロールが存在する場合はそちらのIAMロールに「CloudWatchAgentAdminPolicy」を追加してください。

  • ロール名:CloudWatchAgentAdminRole
  • 許可ポリシー:CloudWatchAgentAdminPolicy
  • また前提としてEC2インスタンスがSystems Managerとの通信ができるように設定をしておく必要がありますので、以下のAWS公式ページを参照してVPCエンドポイント等の設定を実施してください。
    EC2 インスタンス用 AWS Systems Manager のセットアップ(AWS公式)

    【資料ダウンロード】運用のあるべき姿

    Amazon CloudWatchエージェントのインストール

    Amazon Linux 2ではyumコマンドでCloudWatchエージェントのインストールが可能です。

    sudo yum install amazon-cloudwatch-agent

    Amazon Linux 2をご利用出ない場合は、wgetコマンドやcurlコマンドを使用してパッケージファイルをダウンロードし、rpmコマンドにてインストールしてください。

    ※詳細はAWSの公式ドキュメントを参照ください。

    また、今回は使用しませんが、LoadAverageなどの特殊な値を取得したい場合はcollectdが必要となりますのでこのタイミングで併せてインストールしておきましょう。

    # Amazon Linux 2 の場合
    sudo amazon-linux-extras install collectd
    sudo systemctl enable collectd.service
    sudo systemctl start collectd.service
     
    # Amazon Linux 2 以外の場合
    sudo yum install epel-release
    sudo yum install collectd
    sudo systemctl enable collectd.service
    sudo systemctl start collectd.service
    

    CloudWatchエージェントのセットアップ開始

    CloudWatchエージェントのインストールが完了したらセットアップに移ります。以下コマンドを実行して対話形式でのセットアップを開始しましょう。

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

    以下、今回のセットアップ内容です。

    [ec2-user@ip-172-31-41-68 ~]$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
    ================================================================
    = Welcome to the Amazon CloudWatch Agent Configuration Manager =
    =                                                              =
    = CloudWatch Agent allows you to collect metrics and logs from =
    = your host and send them to CloudWatch. Additional CloudWatch =
    = charges may apply.                                           =
    ================================================================
    On which OS are you planning to use the agent?
    1. linux
    2. windows
    3. darwin
    default choice: [1]:
    1
    →Amazon Linux 2を使用してますので「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
    →EC2インスタンスを使用していますので「1」を選択します
    
    
    Which user are you planning to run the agent?
    1. root
    2. cwagent
    3. others
    default choice: [1]:
    1
    →今回は「1」を選択しrootユーザーでCloudwatchエージェントを実行します
    
    
    Do you want to turn on StatsD daemon?
    1. yes
    2. no
    default choice: [1]:
    2
    →StatsDを利用するとアプリケーションやサービスから任意の値を収集できるようになります。
     今回は使用しないため「2」を選択します。
     ・StatsD を使用してカスタムメトリクスを取得する
    https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-custom-metrics-statsd.html
    
    
    Do you want to monitor metrics from CollectD? WARNING: CollectD must be installed or the Agent will fail to start
    1. yes
    2. no
    default choice: [1]:
    2
    →メトリクスの収集にCollectDは使わないため「2」を選択します。
     WARNINGで記載されていますが、CollectDをインストールしていない状態で1を選択してしまうと
     CloudWatchエージェントが起動できなくなってしまいますので注意してください。
    
    
    Do you want to monitor any host metrics? e.g. CPU, memory, etc.
    1. yes
    2. no
    default choice: [1]:
    1
    →「1」を選択します
    
    
    Do you want to monitor cpu metrics per core?
    1. yes
    2. no
    default choice: [1]:
    2
    →CPUをコア毎にモニタリングするかどうか。
     CPU全体の使用率が分かれば良いので「2」を選択します。
    
    
    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
    →デフォルトの「1」を選択します。
    
    
    Do you want to aggregate ec2 dimensions (InstanceId)?
    1. yes
    2. no
    default choice: [1]:
    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
    →デフォルトの「4」でいきます。
    
    
    Which default metrics config do you want?
    1. Basic
    2. Standard
    3. Advanced
    4. None
    default choice: [1]:
    2
    →今回は「2」のスタンダードで設定してみます。
    各メトリクスセットでの収集項目については以下を参照ください
    https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-cloudwatch-agent-configuration-file-wizard.html
    
    
    Current config as follows:
    {
            "agent": {
                    "metrics_collection_interval": 60,
                    "run_as_user": "root"
            },
            "metrics": {
                    "aggregation_dimensions": [
                            [
                                    "InstanceId"
                            ]
                    ],
                    "append_dimensions": {
                            "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
                            "ImageId": "${aws:ImageId}",
                            "InstanceId": "${aws:InstanceId}",
                            "InstanceType": "${aws:InstanceType}"
                    },
                    "metrics_collected": {
                            "cpu": {
                                    "measurement": [
                                            "cpu_usage_idle",
                                            "cpu_usage_iowait",
                                            "cpu_usage_user",
                                            "cpu_usage_system"
                                    ],
                                    "metrics_collection_interval": 60,
                                    "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
                            },
                            "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
    →ここまで入力してきた情報を元にjson形式の設定内容が表示されます
     あとから修正可能ですので「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
    →初期セットアップを想定していますので「2」を選択します
    
    
    Do you want to monitor any log files?
    1. yes
    2. no
    default choice: [1]:
    1
    →ログの収集も実装してみますので「1」を選択します
    
    
    Log file path:
    /var/log/messages
    →今回は「/var/log/messages」を収集することにします
    
    
    Log group name:
    default choice: [messages]
    messages
    →CloudWatch Logs上にログが保存される際のロググループ名を指定します
     今回はデフォルトで表示された「messages」をそのまま使用します
    
    
    Log stream name:
    default choice: [{instance_id}]
    {instance_id}
    →ログストリーム名を指定します。今回はデフォルトの「{instance_id}」を指定します
     どのサーバーのログか判別がつくように設定しておく必要があります
     変数として {instance_id}、{hostname}、{local_hostname}、{ip_address} を使用することができます
    https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html
    
    
    Log Group Retention in days
    1. -1
    2. 1
    3. 3
    4. 5
    5. 7
    6. 14
    7. 30
    8. 60
    9. 90
    10. 120
    11. 150
    12. 180
    13. 365
    14. 400
    15. 545
    16. 731
    17. 1827
    18. 2192
    19. 2557
    20. 2922
    21. 3288
    22. 3653
    default choice: [1]:
    1
    →上記で指定したロググループのログ保持期間ですが、デフォルトの「1」(無制限)で設定します
     ※「1」以外を指定する場合は「logs:PutRetentionPolicy」のIAMポリシー権限が必要です
    
    
    Do you want to specify any additional log files to monitor?
    1. yes
    2. no
    default choice: [1]:
    2
    →「2」を選択します
     追加で監視したいログファイルがある場合は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"
            },
            "logs": {
                    "logs_collected": {
                            "files": {
                                    "collect_list": [
                                            {
                                                    "file_path": "/var/log/messages",
                                                    "log_group_name": "messages",
                                                    "log_stream_name": "{instance_id}",
                                                    "retention_in_days": -1
                                            }
                                    ]
                            }
                    }
            },
            "metrics": {
                    "aggregation_dimensions": [
                            [
                                    "InstanceId"
                            ]
                    ],
                    "append_dimensions": {
                            "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
                            "ImageId": "${aws:ImageId}",
                            "InstanceId": "${aws:InstanceId}",
                            "InstanceType": "${aws:InstanceType}"
                    },
                    "metrics_collected": {
                            "cpu": {
                                    "measurement": [
                                            "cpu_usage_idle",
                                            "cpu_usage_iowait",
                                            "cpu_usage_user",
                                            "cpu_usage_system"
                                    ],
                                    "metrics_collection_interval": 60,
                                    "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
                            },
                            "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
    →生成した設定(config.json)の内容をパラメータストアに保存するか否か
     今回は保存したいので「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_20221211
    →パラメータストアに保存する際の名前を指定します
     命名規則として'AmazonCloudWatch-'から始まる名前で指定する必要があります
     今回は「AmazonCloudWatch-linux_20221211」とします
    
    
    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
    →デフォルトの「ap-northeast-1」を指定します
    
    
    Which AWS credential should be used to send json config to parameter store?
    1. xxxxxxxxxxxxxxxxxxxx(From SDK)
    2. Other
    default choice: [1]:
    1
    →予めEC2インスタンスへCloudWatchAgentAdminPolicyを付与していますので「1」を指定します
    
    
    Successfully put config to parameter store AmazonCloudWatch-linux_20221211.
    Program exits now.
    [ec2-user@ip-172-31-41-68 ~]$
    

    これでパラメータストアの 「AmazonCloudWatch-linux_20221211」 とインスタンス上の 「/opt/aws/amazon-cloudwatch-agent/bin/config.json」 に設定内容が保存されました。

    【資料ダウンロード】運用のあるべき姿

    監視項目追加

    パラメータストア保存された「AmazonCloudWatch-linux_20221211」かインスタンス上に生成された「/opt/aws/amazon-cloudwatch-agent/bin/config.json」を読み込んでCloudWatchエージェントを起動することでセットアップが完了します。

    ただしセットアップウィザードで作成した設定内容にはプロセス監視の項目が含まれていないため、CloudWatchエージェントの起動前に設定内容を修正します。

    こちらのAWS公式ページを参照し、収集対象としたいプロセス用の設定を作成しましょう。

    以下にpid_fileでプロセスを指定し、pid_countでプロセスの起動有無を収集する場合の例を以下に記載します。今回はこちらの設定を追加してみます。

    {
        "metrics": {
            "metrics_collected": {
                "procstat": [
                    {
                        "pid_file":"/var/run/sshd.pid",
                        "measurement": [
                            "pid_count"
                        ]
                    },
                    {
                        "pid_file": "/var/run/crond.pid",
                        "measurement": [
                            "pid_count"
                        ]
                    }
                ]
            }
        }
    }
    

    AWSコンソールからSSMのパラメータストアを開き、「AmazonCloudWatch-linux_20221211」の設定内容を修正しましょう。先程のプロセス用設定を追記すると以下の形となりました。

    {
        "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}",
                            "retention_in_days": -1
                        }
                    ]
                }
            }
        },
        "metrics": {
            "aggregation_dimensions": [
                [
                    "InstanceId"
                ]
            ],
            "append_dimensions": {
                "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
                "ImageId": "${aws:ImageId}",
                "InstanceId": "${aws:InstanceId}",
                "InstanceType": "${aws:InstanceType}"
            },
            "metrics_collected": {
                "cpu": {
                    "measurement": [
                        "cpu_usage_idle",
                        "cpu_usage_iowait",
                        "cpu_usage_user",
                        "cpu_usage_system"
                    ],
                    "metrics_collection_interval": 60,
                    "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
                },
                "swap": {
                    "measurement": [
                        "swap_used_percent"
                    ],
                    "metrics_collection_interval": 60
                },
                "procstat": [
                    {
                        "pid_file": "/var/run/sshd.pid",
                        "measurement": [
                            "pid_count"
                        ]
                    },
                    {
                        "pid_file": "/var/run/crond.pid",
                        "measurement": [
                            "pid_count"
                        ]
                    }
                ]
            }
        }
    }
    

    また、収集不要な項目等がある場合はこのタイミングで設定から消してしまいましょう。大規模なシステムの場合は不要なメトリクスを大量に収集してしまうと無視できないレベルの利用料金が発生してしまう可能性があるためです。

    参考リンク:CloudWatch の使用に対して課金された理由を理解し、今後の請求額を減らすにはどうすればいいですか?(AWS公式)

    CloudWatchエージェントの起動

    設定内容の修正が完了したらいよいよCloudWatchエージェントを起動します。今回はパラメータストアに保存した設定を修正していますので「パラメータストアに保存した設定を読み込んで起動する場合」のコマンドを実行してください。

    # インスタンス内に生成されたconfig.jsonをから設定を読み込んで起動する場合
    sudo /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
    
    # パラメータストアに保存した設定を読み込んで起動する場合
    sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c ssm:AmazonCloudWatch-linux_20221211 -s
    

    起動が完了したら以下コマンドでCloudWatchエージェントのステータスを確認します。statusがrunningとなっていることを確認してください。

    # 起動状態の確認
    $ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status
    {
      "status": "running",
      "starttime": "2022-12-20T09:34:15+0000",
      "configstatus": "configured",
      "cwoc_status": "stopped",
      "cwoc_starttime": "",
      "cwoc_configstatus": "not configured",
      "version": "1.247354.0b251981"
    }
    

    ここまで来たらCloudWatchエージェントのセットアップは完了です。

    AWSのマネジメントコンソールから「CloudWatch」→「すべてのメトリクス」を開き、メトリクスの収集状況を確認してください。

    正しく設定できていれば以下のようにグラフ化されて表示されます。

    Amazon Cloudwatch メトリクスの収集状況

    2台目以降のインスタンスでのセットアップ

    2台目以降のインスタンスではCloudWatchエージェントのセットアップウィザードは実行不要となり、1台目のセットアップ時にパラメータストアに保存した設定を読み込ませて起動させるだけでセットアップが完了します。

    パラメータストア上に保存されている設定を読み込む権限を持つポリシー「CloudWatchAgentServerPolicy」を付与したIAMロールを作成し、EC2に割り当ててください。

    今回は以下のIAMロールを作成・付与しましたが、既にEC2へ割り当てているIAMロールが存在する場合はそちらのIAMロールに「CloudWatchAgentServerPolicy」を追加してください。

  • ロール名:CloudWatchAgentServerRole
  • 許可ポリシー:CloudWatchAgentServerPolicy
  • # CloudWatchエージェントのインストール及び起動
    sudo yum install amazon-cloudwatch-agent
    sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c ssm:AmazonCloudWatch-linux_20221211 -s
    

    上記2行のコマンドを実行するだけでセットアップが完了します。

    まとめ

    CloudWatchエージェントを初めて利用する方に向けたセットアップ方法をご紹介させていただきましたがいかがでしたでしょうか。
    また、今回はご紹介しませんでしたがパラメータストアに保存した設定とSystem ManagerのRun Command機能を活用することでCloudWatchエージェントのインストールからセットアップまでを複数のサーバーに対して一斉に実施することも可能です。

    他にもSystems Managerの活用例を以下でご紹介させていただいておりますので宜しければ御覧ください。

    AWS Systems Manager (SSM) で考える、運用の自動化

    【資料ダウンロード】運用のあるべき姿