k8s運用でinotify_init: too many open filesを検知した話

はじめに

さくらのオブジェクトストレージのバックエンドはk8sで運用しています。 開発環境のk8sはさくらのクラウド上で稼働しており、マスター3台、ワーカー5台の構成です。

この内、5番目のワーカーで起動しているkubeletが何度も再起動を繰り返し、 Alertmanagerから断続的にアラートが送られて来ました。

その時に、kubeletのjournalログから表題のエラーを発見し対応したため、記事にしました。

原因の調査

下記は当時のログの一部を抜き出したものです。

ubuntu@worker05:~$ journalctl -exu kubelet --no-pager | grep E0517 | sed 's/\(.*\)E0517.*]\(.*\)/\2/' | sort | uniq
 "Failed to start cAdvisor" err="inotify_init: too many open files"
 "Unable to read config path" err="unable to create inotify: too many open files" path="/etc/kubernetes/manifests"
 Error initializing dynamic plugin prober: Error initializing watcher: too many open files
 Registration of the raw container factory failed: inotify_init: too many open files
ubuntu@worker05:~$

kubeletのエラーを見てみると、inotify_inittoo many open filesが目立ちます。

inotify_init

inotify_initについて調べるために、man inotify_initとコマンドを打ち、内容を見てみると

inotify_init()  initializes a new inotify instance and returns a file descriptor associated with a new inotify event queue.

とあり、「新規のinotifyインスタンスを初期化し、作成されたinotifyイベントキューに対応するファイルディスクリプタを返す」ことがわかります。

なお、inotifyとは(こちらも man inotify でわかりますが)、ファイルシステムイベントを監視するための機構であり、ファイルやディレクトリの監視などに用いられます。

ここでは、cAdvisorcgroupツリーを監視するために利用しようとしていたことがログからわかります。

参考: https://github.com/google/cadvisor/issues/2363

原因

少なくとも「inotify_initの際にファイルディスクリプタを確保できなかった」ことによるエラーが原因であることがわかりました。

対応

そこで、issueにある通り、

  • max_user_instance: 実ユーザID毎に生成可能なinotifyインスタンスの上限を指定する
  • max_user_watcher: ユーザID毎に作成可能な監視対象の上限を指定する

の数を調整します。

元々のinotify関連のパラメータ値は、

root@worker05:~# sysctl -a | grep "fs.inotify"
fs.inotify.max_queued_events = 16384
fs.inotify.max_user_instances = 128
fs.inotify.max_user_watches = 8192
root@worker05:~# 

であったため、

sudo sysctl fs.inotify.max_user_instances=512
sudo sysctl fs.inotify.max_user_watches=65536

を実行し、

root@worker05:~# sysctl -a | grep "fs.inotify"
fs.inotify.max_queued_events = 16384
fs.inotify.max_user_instances = 512
fs.inotify.max_user_watches = 65536
root@worker05:~# 

に変更しました。

その後、当該エラーは発生しなくなったことを確認できました。

おわり