EC2のメモリ監視をCloudWatch Agentで実施してみた

AWSチームのすずきです。

EC2インスタンス(Amazon Linux 2) のメモリ使用率の監視を行うため、 CloudWatch Agent を設定する機会がありましたので、紹介させていただきます。

環境

以下のEC2インスタンスを対象としました。

  • インスタンスタイプ : m5.large
  • OS: Amazon Linux 2
  • AMI : amzn2-ami-hvm-2.0.20191217.0-x86_64-gp2 (ami-011facbea5ec0363b)

UserData

CloudWatch Agent は、UserDataを利用し、EC2インスタンスの起動時に設定しました。

#cloud-config
runcmd:
  - [ sh, -c, "dd if=/dev/zero of=/swapfile bs=1M count=512" ]
  - [ sh, -c, "chmod 600 /swapfile; mkswap /swapfile; swapon /swapfile" ]
  - [ sh, -c, "echo '/swapfile swap swap defaults 0 0' >> /etc/fstab" ]
  - [ sh, -c, "rpm -Uvh https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm" ]
  - /opt/aws/amazon-cloudwatch-agent/bin/config-translator --input /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json --output /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml --mode ec2
  - /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a start
write_files:
- content: |
    {
      "metrics": {
        "append_dimensions": {
          "ImageId": "${aws:ImageId}",
          "InstanceId": "${aws:InstanceId}",
          "InstanceType": "${aws:InstanceType}"
        },
        "metrics_collected": {
          "mem": {
            "measurement": [
              "mem_used_percent"
            ],
            "metrics_collection_interval": 60
          },
          "swap": {
            "measurement": [
              "swap_used_percent"
            ],
            "metrics_collection_interval": 60
          }
        }
      }
    }
  mode: '000600'
  owner: root
  group: root
  path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json

SWAP設定

メモリ不足の指標とするため小容量のスワップを設置しました。

dd if=/dev/zero of=/swapfile bs=1M count=512
chmod 600 /swapfile; mkswap /swapfile; swapon /swapfile
echo '/swapfile swap swap defaults 0 0' >> /etc/fstab

CloudWatch Agent 設定

S3 ダウンロードリンクを利用して、CloudWatch エージェントをインストールしました。

rpm -Uvh https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm

サーバーで CloudWatch エージェントをインストールして実行する

CloudWatch Agent の設定は、JSONからTOML形式に変換して利用しました。

/opt/aws/amazon-cloudwatch-agent/bin/config-translator --input /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json --output /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml --mode ec2

amazon-cloudwatch-agent.json

{
  "metrics": {
    "append_dimensions": {
      "ImageId": "${!aws:ImageId}",
      "InstanceId": "${!aws:InstanceId}",
      "InstanceType": "${!aws:InstanceType}"
    },
    "metrics_collected": {
      "mem": {
        "measurement": [
          "mem_used_percent"
        ],
        "metrics_collection_interval": 60
      },
      "swap": {
        "measurement": [
          "swap_used_percent"
        ],
        "metrics_collection_interval": 60
      }
    }
  }
}

amazon-cloudwatch-agent.toml


[agent]
  collection_jitter = "0s"
  debug = false
  flush_interval = "1s"
  flush_jitter = "0s"
  hostname = ""
  interval = "60s"
  logfile = "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log"
  metric_batch_size = 1000
  metric_buffer_limit = 10000
  omit_hostname = false
  precision = ""
  quiet = false
  round_interval = false

[inputs]

  [[inputs.mem]]
    fieldpass = ["used_percent"]
    interval = "60s"
    [inputs.mem.tags]
      metricPath = "metrics"

  [[inputs.swap]]
    fieldpass = ["used_percent"]
    interval = "60s"
    [inputs.swap.tags]
      metricPath = "metrics"

[outputs]

  [[outputs.cloudwatch]]
    force_flush_interval = "60s"
    namespace = "CWAgent"
    region = "ap-northeast-1"
    tagexclude = ["host", "metricPath"]
    [outputs.cloudwatch.tagpass]
      metricPath = ["metrics"]

[processors]

  [[processors.ec2tagger]]
    ec2_metadata_tags = ["ImageId", "InstanceId", "InstanceType"]
    refresh_interval_seconds = "2147483647s"
    [processors.ec2tagger.tagpass]
      metricPath = ["metrics"]

IAM

AWS管理ポリシー「CloudWatchAgentServerPolicy」をアタッチしたEC2ロールを用意しました。

  • arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy

動作確認

監視対象のEC2インスタンスで「stress」コマンドを実行。7〜7.5GBのメモリを消費した状態を発生させました。

sudo rpm -Uvh http://ftp.riken.jp/Linux/dag/redhat/el7/en/x86_64/rpmforge/RPMS/stress-1.0.2-1.el7.rf.x86_64.rpm
nohup stress --vm 7 --vm-bytes 1024M --vm-keep &
nohup stress -m 2 -q &
Tasks: 105 total,   9 running,  56 sleeping,   0 stopped,   0 zombie
%Cpu(s): 60.0 us, 40.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  7865340 total,   329712 free,  7510412 used,    25216 buff/cache
KiB Swap:   524284 total,   300548 free,   223736 used.   206404 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
25103 ssm-user  20   0 1056152   1.0g      4 R  20.0 13.3   2:11.10 stress --vm 7 --vm-bytes 1024M --vm-keep
25133 ssm-user  20   0  269720   7304    136 R  20.0  0.1   0:35.66 stress -m 2 -q
25097 ssm-user  20   0 1056152   1.0g      4 R  16.0 13.3   2:11.80 stress --vm 7 --vm-bytes 1024M --vm-keep
25099 ssm-user  20   0 1056152   1.0g      4 R  16.0 13.3   2:03.78 stress --vm 7 --vm-bytes 1024M --vm-keep
25100 ssm-user  20   0 1056152   1.0g      4 R  16.0 13.3   0:30.78 stress --vm 7 --vm-bytes 1024M --vm-keep
  433 root      20   0       0      0      0 S  12.0  0.0   0:06.07 [kswapd0]
25101 ssm-user  20   0 1056152   1.0g      4 R  12.0 13.3   0:31.45 stress --vm 7 --vm-bytes 1024M --vm-keep
25132 ssm-user  20   0  269720 168344    136 R  12.0  2.1   0:35.74 stress -m 2 -q
25098 ssm-user  20   0 1056152 985772      4 D   4.0 12.5   0:03.09 stress --vm 7 --vm-bytes 1024M --vm-keep

CloudWatch

指定したインスタンスIDのカスタムメトリックとして、 メモリ使用率が「mem_used_percent」、スワップ使用率が「swap_used_percent」として表示されました。

料金

1台のEC2インスタンスより、2つのカスタムメトリックを1分ごとに30日間連続して登録した場合、CloudWatchで発生するAWS費用は1ドルとなります。

  • 最初の 10,000 個のカスタムメトリクス (1 個あたり 0.30 USD) = 2 メトリクス x 0.30 USD = 0.6 USD
  • 1,000,001~440,640,000 件までの API リクエストの課金 (1000リクエスト毎に 0.01 USD) = 43,200(分) / 1000 x 0.01 = 0.43USD

Amazon CloudWatch の料金

まとめ

CloudWatch エージェントを利用する事で、メモリ、スワップ使用率をカスタムメトリックで監視、可視化可能になります。

メモリ不足の傾向が確認出来た場合には、稼働状況の詳細を確認した上でインスタンスタイプのスペックアップやメモリ最適化インスタンス(R5)への変更をご検討ください。

CloudWatch エージェント、メモリ使用率の監視以外に、CPUやディスクなどのカスタムメトリックや、ログファイルのCloudWatchLogsへの集約にも利用できます。

新しいCloudWatch Agentでメトリクスとログの収集が行なえます

CloudWatch エージェントの導入対象のEC2インスタンスが多数ある場合や、設定変更が予想される場合には、Systems Manager(SSM) もお試しください。

CloudWatch AgentをEC2にログインせずに設定してみた

テンプレート

今回利用した環境を再現するCloudFormationテンプレートです。