この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
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
まとめ
CloudWatch エージェントを利用する事で、メモリ、スワップ使用率をカスタムメトリックで監視、可視化可能になります。
メモリ不足の傾向が確認出来た場合には、稼働状況の詳細を確認した上でインスタンスタイプのスペックアップやメモリ最適化インスタンス(R5)への変更をご検討ください。
CloudWatch エージェント、メモリ使用率の監視以外に、CPUやディスクなどのカスタムメトリックや、ログファイルのCloudWatchLogsへの集約にも利用できます。
CloudWatch エージェントの導入対象のEC2インスタンスが多数ある場合や、設定変更が予想される場合には、Systems Manager(SSM) もお試しください。
テンプレート
今回利用した環境を再現するCloudFormationテンプレートです。