クローラー等のバッチサービスなんかを可動させているとそのうちディスク容量不足になってダウンするなんてことが考えられます。
...いやまぁ実際に私の身に起きた話ではあるんですが😇

この問題を防ぐなら理想は常に十分な容量を確保することですが、容量を増やせば当然お金もかかります。
今は使わない容量を無駄に確保してもお金の無駄なので、空き容量が十分でなくなってきた段階で通知して事前に対処することにしましょう。
更に自動的に不要なものをバックアップしてクリーンするようなスクリプトを用意したらほぼほぼ完璧ではなかろうか。

ここではAWSのEC2とCloudWatchを使ったディスク容量の監視と通知方法についてまとめます。

前提環境

サーバー

AWSのEC2上にAmazon Linuxを走らせている

ボリューム

AWSのELASTIC BLOCK STOREを2個使用中
rootとhomeでそれぞれ任意のサイズで分割

やりたいこと

root(/)とhome(/home)の複数のボリュームの空き容量が一定以下になったらメールで通知したい

実現方法

CloudWatch Monitoring Scriptsを監視対象のサーバーで定期的に実行してCloud Watchに反映させ、Cloud Watchのアラームでメール通知する

公式ドキュメント

Amazon EC2 Linux インスタンスのメモリとディスクのメトリクスのモニタリング

ここに全部書いてありました😓

必要なパッケージを導入

sudo yum install perl-Switch perl-DateTime perl-Sys-Syslog perl-LWP-Protocol-https -y

AmazonLinux 2の場合は

sudo yum install perl-Digest-SHA.x86_64

も必要です

実行スクリプトを配置する場所を決める

ここでは仮に~/cron-script に配置することにします。

mkdir ~/cron-script
cd ~/cron-script

必要なスクリプトをダウンロードして展開

curl https://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.2.zip -O
unzip CloudWatchMonitoringScripts-1.2.2.zip
rm CloudWatchMonitoringScripts-1.2.2.zip
cd aws-scripts-mon

監視用のユーザーを追加する

AWSコンソール上で新しいユーザーを追加します。

権限の追加

追加したユーザーに、CloudWatchAgentServerPolicyポリシーを適用しておけばとりあえず動きます(不要な権限ははずすべきですが)
また公式にあるように過去の送信記録などを確認する場合は更に下記の権限を追加しないとダメです。

  • cloudwatch:GetMetricStatistics
  • cloudwatch:ListMetrics

認証情報の設定

cp awscreds.template awscreds.conf

でテンプレートをコピーして、

nano awscreds.conf

で追加したユーザーのAWSAccessKeyIdとAWSSecretKeyを適切に設定します。

テスト

./mon-put-instance-data.pl --mem-util --verify --verbose

でローカルで確認できます。--verifyオプションなのでCloud Watchには送信されません。

目的のオプションを追加してテスト

今回は空き容量を知るために、--disk-space-utilオプションを追加します。
これは--disk-path=PATHで指定されたパスのディスク使用率(%)をレポートします。
更に、今回は複数のディスク容量を知りたいので、--disk-path=/ --disk-path=/homeを追加します。
他のオプションは公式ドキュメントを参照してください。

./mon-put-instance-data.pl --disk-space-util --disk-path=/ --disk-path=/home --verify --verbose

定期実行させる

確認ができたらcronで定期的に実行させます。

crontab -e

してエディタを起動して下記の内容を入力して保存します。

*/5 * * * * ~/cron-script/aws-scripts-mon/mon-put-instance-data.pl --mem-used-incl-cache-buff --mem-util --disk-space-util --disk-path=/ --disk-path=/home --from-cron

※5分間隔でメモリ周りの情報も追加して、テスト用のオプションを削除してます。

CloudWatchで確認

ここまできたらCloudWatch上で[メトリクス]->[すべてのメトリクス]->[Linuxシステム]->[Filesystem, InstanceId, MountPath]に、それぞれのマウントの使用率が表示されるはず。
表示されない場合は少し待つかcronがちゃんと実行されているかを下記で確認します。

sudo tail /var/log/cron

アラームの設定

最後に[アラーム]->[アラームの作成]で[Linuxシステム]->[Filesystem, InstanceId, MountPath]で対象のファイルシステムを選択。
[次へ]を押して名前と説明を適当に決めて好きなしきい値を入力、警告状態の場合の通知先を設定したら完了
ちなみに今回はファイルシステムが複数あるので複数回作る必要があります。

これで大丈夫です。
本番テストする場合は、fallocate等でダミーの巨大データを生成してアラームを確認すると良いです。

本当は障害が発生したら通知ではなく、障害が発生していないなら通知、がより安全なんですが実際やってみると鬱陶しいんですよね。