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_init
とtoo 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
でわかりますが)、ファイルシステムイベントを監視するための機構であり、ファイルやディレクトリの監視などに用いられます。
ここでは、cAdvisor
がcgroup
ツリーを監視するために利用しようとしていたことがログからわかります。
参考: 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:~#
に変更しました。
その後、当該エラーは発生しなくなったことを確認できました。
おわり