CloudWatchのモニタリングスクリプトでハマった話
CloudWatchのモニタリングスクリプト設定してあるのに、該当のインスタンスIDのデータがCloudWatchにputDataされていなくてハマった話。
ハマったインスタンスは、すでにクラウドウォッチが設定してあるAMIから立ち上げたインスタンスで、 AMIに配置されている、CloudWatchにputDataするスクリプト自体は、インスタンスIDに依存していないから、 そのまま問題なく正しいインスタンスIDでputDataされるはず。
だが、実際はAMI作成ものインスタンスIDでメトリクスが登録されてしまう。。
インスタンスIDを確認
# curl -s http://169.254.169.254/latest/meta-data/instance-id i-xxxxxxxx
- CentOS6.6にCloudWatchを設定する。
で紹介したスクリプトを利用している。
# /usr/bin/check_cw_stats MemoryUtilization: 12.86724312544 (Percent) DiskSpaceUtilization [/]: 6.65698036312681 (Percent) Using AWS credentials file </etc/aws/awscreds.conf> Endpoint: https://monitoring.ap-northeast-1.amazonaws.com Payload: {"MetricData":[{"Timestamp":1460957603,"Dimensions":[{"Value":"i-yyyyyyyy","Name":"InstanceId"}],"Value":12.86724312544,"Unit":"Percent","MetricName":"MemoryUtilization"},{"Timestamp":1460957603,"Dimensions":[{"Value":"/dev/xvda1","Name":"Filesystem"},{"Value":"i-yyyyyyyy","Name":"InstanceId"},{"Value":"/","Name":"MountPath"}],"Value":6.65698036312681,"Unit":"Percent","MetricName":"DiskSpaceUtilization"}],"Namespace":"System/Linux","__type":"com.amazonaws.cloudwatch.v2010_08_01#PutMetricDataInput"} Received HTTP status 200 on attempt 1 Successfully reported metrics to CloudWatch. Reference Id: 1038cd0d-0527-11e6-b8f3-fbed7fa60205
あきらかに、PayloadのインスタンスIDが実際にインスタンスメタデータで取得したInstanceIdと異なっている。 ちなみにi-yyyyyyyyのインスタンスIDはAMIのインスタンスIDになる。
AWSから提供されているCloudWatch登録のスクリプトをおってみる。
- /usr/local/src/CloudWatch-1.0.20.0/aws-scripts-mon/mon-put-instance-data.pl
338: my $instance_id = CloudWatchClient::get_instance_id();
- /usr/local/src/CloudWatch-1.0.20/aws-script-mon
sub get_instance_id ... { if (!$instance_id) { $instance_id = get_meta_data('/instance-id', USE_CACHE); } return $instance_id; } ...
USE_CACHEだと!!というわけで、キャッシュをするようです。
よくよくAmazon EC2 Linux インスタンスのメモリとディスクのメトリックスのモニタリングを読んでみると以下のようにキャシュに関する文章が。
スクリプトパッケージに含まれる CloudWatchClient.pm モジュールは、インスタンスのメタデータをローカルでキャッシュします。スクリプトを実行しているインスタンスから AMI を作成すると、キャッシュ TTL(デフォルト: 6 時間、Auto Scaling グループでは 24 時間)以内にこの AMI から起動したすべてのインスタンスは、元のインスタンスの ID を使用してメトリックスを出力します。キャッシュ TTL 期間が経過した後は、スクリプトは新しいデータを取得し、スクリプトは現在のインスタンスの ID を使用します。これをすぐに修正するには、$ rm /var/tmp/aws-mon/instance-id を使用してキャッシュされたデータを削除します
気を取り直し、キャッシュを削除
rm -rf /var/tmp/aws-mon/*
再度メトリクススクリプトの実行。
# /usr/bin/check_cw_stats MemoryUtilization: 13.8519340228981 (Percent) DiskSpaceUtilization [/]: 6.65734560054434 (Percent) Using AWS credentials file </etc/aws/awscreds.conf> Endpoint: https://monitoring.ap-northeast-1.amazonaws.com Payload: {"MetricData":[{"Timestamp":1460958577,"Dimensions":[{"Value":"i-xxxxxxxx","Name":"InstanceId"}],"Value":13.8519340228981,"Unit":"Percent","MetricName":"MemoryUtilization"},{"Timestamp":1460958577,"Dimensions":[{"Value":"/dev/xvda1","Name":"Filesystem"},{"Value":"i-xxxxxxxx","Name":"InstanceId"},{"Value":"/","Name":"MountPath"}],"Value":6.65734560054434,"Unit":"Percent","MetricName":"DiskSpaceUtilization"}],"Namespace":"System/Linux","__type":"com.amazonaws.cloudwatch.v2010_08_01#PutMetricDataInput"} Received HTTP status 200 on attempt 1
となり、正しいインスタンスIDでputDataができました。
ということで、AMIなどから新しいインスタンス、オートスケールなどを実行する際には、
ユーザーデータで
#!/bin/bash rm -rf /var/tmp/aws-mon/*
と設定しておけば安心です。