こんにちは、ちゃりおです。
CloudWatchエージェントがたまに落ちることがありました。
調べるとファイルディスクリプタの問題みたいでした。
解消法について書きます。
コマンドは、AmazonLinux2で実行しました。
CloudwatchAgent too many filesでエージェントが落ちる事象
事象について
EC2にCloudWatchエージェントをインストールして、ログやメトリクスを送っていました。
1ヶ月に一回くらいの頻度で、CloudWatchエージェントのサービスが停止してログ・メトリクスが送れなくなっています。
CloudWatchエージェントを再起動することで、一時的に解消しますがまた1ヶ月くらい経つと停止します。
CloudWatchエージェントのログを見てみると、「too many files」がよくでています。
原因
CloudWatchエージェントのプロセスが、ファイルディスクリプタの上限を超えた。
結果、これ以上ファイルを開くことができなくなりログやメトリクスを送信できなくなった。
下記のコマンドで確認したところ、事象の発生時は上限値を超えていた。
CloudWatchエージェント再起動後も、日毎に確認したところ値が増えていた。
$ sudo ps -C amazon-cloudwatch-agent -o pid= #pidを出力
sudo cat /proc//limits | grep “Max open files” #上限値を出力
Max open files <ソフトリミット> <ハードリミット>
$ sudo lsof -p | wc -l #CloudWatchエージェントが開いているファイルの数
通常、ファイルディスクリプタは0から順番に未使用の最も小さい値が与えられるようになっており、プログラム上では整数型の変数などとして扱われる。ただし、番号によっては固定的に特殊な対象を表す場合があり、一般的には「0」は標準入力(stdin)、「1」は標準出力(stdout)、「2」は標準エラー出力(stderr)としてプログラムの実行中は常に開いた状態になっている。
ファイルディスクリプタには上限値があり、これを超える数のファイルを同時に開くことはできない。上限値はプロセスごとの値とOS全体の値が決まっており、システムや設定によって具体的な値は異なる。Linuxなど多くのシステムでは初期値がプロセスごとの上限が1024に設定されていることが多い。16ビットの整数値が表現できる上限である65535を超える値を指定することはできない。
解決策
CloudWatchエージェントのファイルディスクリプタの上限を上げる。
プロセスごとに上限値を上げる方法を紹介します。
$ sudo vi /etc/systemd/system/amazon-cloudwatch-agent.service.d/override.conf
[Service]
LimitNOFILE=10000
$ sudo systemctl daemon-reload
$ sudo systemctl restart amazon-cloudwatch-agent
$ sudo cat /proc//limits | grep “Max open files” #上限値が増えているはず
参考 systemd で ulimit 上げるときの推奨の方法
まとめ
CloudWatchエージェントのファイルディスクリプタの上限を上げる方法についてでした。
ログファイルの数が多いと発生しやすいです。
デイリーでログファイルを作成していて、CloudWatchエージェントのconfでhoge.*みたいにしていると多くなりがちです。
上限値をあげることで解決できますが、ログの出し方も考えたほうがいいかもしれません。