Kubernetes Meetup Tokyo #56 (2023/03/16)
SUDA Kazuki, Preferred Networks, Inc. (@superbrothers)
Kubernetes + containerd で cgroup v2 に移⾏したら
“failed to create fsnotify watcher” エラーが
発⽣する原因と対策
@superbrothers

SUDA Kazuki / @superbrothers
▶ Preferred Networks, Inc. / エンジニア
▶ Scalar, Inc., Datachain, Inc. / 技術アドバイザ
▶ Kubernetes Meetup Tokyo, K8s@home 共同主催者
▶ 技術評論社「Kubernetes実践⼊⾨」、「みんなのDocker/Kubernetes」共著書
▶ オライリー「⼊⾨ Prometheus」、「Kubernetes で実践するクラウドネイティブ DevOps」監訳書
▶ stern ツールメンテナ(https://github.com/stern/stern)
2
@superbrothers

cgroup v2 に移⾏したらエラーが発⽣した
3
$ journalctl -u kubelet -f
Insufficient watch descriptors available. Reverting to -n.
$ kubectl logs -f deploy/nginx
failed to create fsnotify watcher: too many open files
@superbrothers

そもそも cgroup v2 に移⾏すると何がうれしいの(利⽤者視点)
Pod のメモリ要求が保証され、メモリ使⽤量が増加した際の Pod の安定性が向上する。
▶ requests.memory を下回ってシステムにメモリを回収されることがなくなる
▶ limits.memory の80%を超えて使⽤するとシステムがメモリを回収してできる限り OOM Kill を発⽣
しにくくする
4
* Quality-of-Service for Memory Resources | Kubernetes
これまでは Podスケジューリングと
Node MemoryPressure時に
どの Pod をevict するかの
判断に使われていました
@superbrothers

原因調査 (1/3)
containerd-shim processes are leaking inotify instances with cgroups v2 · issue #5670 · containerd/
containerd
▶ cgroup v2 使⽤時にメモリイベント監視⽤の inotify instances がリークしているという報告
+ 調査時点ですでに上記が修正済みの containerd バージョンを使⽤していた
▶ しかし、ここで containerd は cgroup v2 使⽤時に inotify instances を使うようになったことを知る
▶ Ubuntu 20.04/22.04 はデフォルトの上限が 128 なので、上限に達している😅
5
$ sudo find /proc/*/fd -lname anon_inode:inotify | wc -l
128
@superbrothers

原因調査 (2/3)
▶ containerd-shim プロセスあたり2つ以上の inotify instances を使⽤していることが分かる
6
$ sudo find /proc/*/fd -lname anon_inode:inotify | cut -d/ -f3 | xargs -I '{}' -- ps --
no-headers -o '%p %U %c %a %P' -p '{}' | uniq -c | sort -nr | grep containerd-shim
7 2855 root containerd-shim /usr/local/bin/containerd-s 1
5 2737 root containerd-shim /usr/local/bin/containerd-s 1
4 2694 root containerd-shim /usr/local/bin/containerd-s 1
3 8229 root containerd-shim /usr/local/bin/containerd-s 1
3 7982 root containerd-shim /usr/local/bin/containerd-s 1
3 7859 root containerd-shim /usr/local/bin/containerd-s 1
3 7117 root containerd-shim /usr/local/bin/containerd-s 1
2 7720 root containerd-shim /usr/local/bin/containerd-s 1
2 7660 root containerd-shim /usr/local/bin/containerd-s 1
2 7569 root containerd-shim /usr/local/bin/containerd-s 1
2 7494 root containerd-shim /usr/local/bin/containerd-s 1
2 7433 root containerd-shim /usr/local/bin/containerd-s 1
2 4260 root containerd-shim /usr/local/bin/containerd-s 1
1つの Pod に相当
@superbrothers

原因調査 (3/3)
▶ Ubuntu 20.04/22.04 ではデフォルトで inotify instances の上限が 128
▶ containerd は cgroup v2 使⽤時に Pod あたり2つの inotify instances を使⽤する
▶ 1ノード上に作成できる Pods 数は 110 (デフォルト)なので、64の Pod が作成されると
それだけで inotify instances の上限に達してしまいエラーが発⽣する
7
@superbrothers

対策
inotify instances の上限を上げる
▶ 値は⼗分に⼤きければよい
+ inotify instances は実際に作成されなければリソースを消費しない
8
# /etc/sysctl.conf
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=524288
@superbrothers

で、containerd は何のために inotify を使ってるの
コンテナの OOM イベントを知るため
▶ Inotify は Linux カーネルでサポートされているファイルシステムイベント通知システムで、
ファイルシステム上のファイルやディレクトリに対するさまざまなアクション(作成、変更、
削除、移動など)に対して、カーネルがユーザースペースに通知できる
▶ OOM を含むメモリイベントを知るのに cgroup v2 の memory サブシステムで使⽤され
る ”memory.events” ファイルを監視するのに inotify を使⽤している
▶ Pod あたり2つの inotify instances を使⽤するのは、
Pod が少なくともアプリケーションコンテナと pause コンテナの2つから構成されるため
9
内部的にすべての Pod に必ず存在する特殊なコンテナで、
Pod のコンテナ間で名前空間を共有するためなどに使われる
@superbrothers

より詳しくは
▶ Kubernetes: cgroup v2 使⽤時に "failed to create fsnotify watcher: too many open
fi
les" エラーが発
⽣する問題の対策 - Qiita
10
環境情報
▶ OS: Ubuntu 22.04.1 LTS
▶ Kubernetes: v1.25.5
▶ containerd: v1.6.12
機械学習プラットフォームエンジニア
We're hiring! https://www.preferred.jp/ja/careers/
▶ ⾃由度・拡張性・使いやすさのトレードオフが取れた⼤規模機械学習プラットフォームの機能設計と開発
+ 例: 機械学習ワークフローツール、実験管理ツール、GPUやMN-Core向け統合開発環境の構築
▶ ⼤規模機械学習プラットフォームの運⽤と運⽤改善(⾃動化等)
+ 例: ⾃動サーバプロビジョニング、パブリッククラウド連携による運⽤効率化、
インフラ健全性の⾃動診断と保守省⼒化
▶ ⼤規模機械学習プラットフォーム上での計算資源(GPU, MN-Coreを含む)配分の最適化
+ 例: Kubernetes Schedulerの機能拡張、リソース利⽤量制限拡張の開発
▶ 最先端の分散計算基盤技術の Proof of Concept 構築及びプラットフォームでの実⽤化
+ 例: Kubernetes上での分散強化学習実⾏ツール

Kubernetes + containerd で cgroup v2 に移行したら "failed to create fsnotify watcher" エラーが発生する原因と対策 / Kubernetes Meetup Tokyo #56

  • 1.
    Kubernetes Meetup Tokyo#56 (2023/03/16) SUDA Kazuki, Preferred Networks, Inc. (@superbrothers) Kubernetes + containerd で cgroup v2 に移⾏したら “failed to create fsnotify watcher” エラーが 発⽣する原因と対策
  • 2.
    @superbrothers  SUDA Kazuki /@superbrothers ▶ Preferred Networks, Inc. / エンジニア ▶ Scalar, Inc., Datachain, Inc. / 技術アドバイザ ▶ Kubernetes Meetup Tokyo, K8s@home 共同主催者 ▶ 技術評論社「Kubernetes実践⼊⾨」、「みんなのDocker/Kubernetes」共著書 ▶ オライリー「⼊⾨ Prometheus」、「Kubernetes で実践するクラウドネイティブ DevOps」監訳書 ▶ stern ツールメンテナ(https://github.com/stern/stern) 2
  • 3.
    @superbrothers  cgroup v2 に移⾏したらエラーが発⽣した 3 $journalctl -u kubelet -f Insufficient watch descriptors available. Reverting to -n. $ kubectl logs -f deploy/nginx failed to create fsnotify watcher: too many open files
  • 4.
    @superbrothers  そもそも cgroup v2に移⾏すると何がうれしいの(利⽤者視点) Pod のメモリ要求が保証され、メモリ使⽤量が増加した際の Pod の安定性が向上する。 ▶ requests.memory を下回ってシステムにメモリを回収されることがなくなる ▶ limits.memory の80%を超えて使⽤するとシステムがメモリを回収してできる限り OOM Kill を発⽣ しにくくする 4 * Quality-of-Service for Memory Resources | Kubernetes これまでは Podスケジューリングと Node MemoryPressure時に どの Pod をevict するかの 判断に使われていました
  • 5.
    @superbrothers  原因調査 (1/3) containerd-shim processesare leaking inotify instances with cgroups v2 · issue #5670 · containerd/ containerd ▶ cgroup v2 使⽤時にメモリイベント監視⽤の inotify instances がリークしているという報告 + 調査時点ですでに上記が修正済みの containerd バージョンを使⽤していた ▶ しかし、ここで containerd は cgroup v2 使⽤時に inotify instances を使うようになったことを知る ▶ Ubuntu 20.04/22.04 はデフォルトの上限が 128 なので、上限に達している😅 5 $ sudo find /proc/*/fd -lname anon_inode:inotify | wc -l 128
  • 6.
    @superbrothers  原因調査 (2/3) ▶ containerd-shimプロセスあたり2つ以上の inotify instances を使⽤していることが分かる 6 $ sudo find /proc/*/fd -lname anon_inode:inotify | cut -d/ -f3 | xargs -I '{}' -- ps -- no-headers -o '%p %U %c %a %P' -p '{}' | uniq -c | sort -nr | grep containerd-shim 7 2855 root containerd-shim /usr/local/bin/containerd-s 1 5 2737 root containerd-shim /usr/local/bin/containerd-s 1 4 2694 root containerd-shim /usr/local/bin/containerd-s 1 3 8229 root containerd-shim /usr/local/bin/containerd-s 1 3 7982 root containerd-shim /usr/local/bin/containerd-s 1 3 7859 root containerd-shim /usr/local/bin/containerd-s 1 3 7117 root containerd-shim /usr/local/bin/containerd-s 1 2 7720 root containerd-shim /usr/local/bin/containerd-s 1 2 7660 root containerd-shim /usr/local/bin/containerd-s 1 2 7569 root containerd-shim /usr/local/bin/containerd-s 1 2 7494 root containerd-shim /usr/local/bin/containerd-s 1 2 7433 root containerd-shim /usr/local/bin/containerd-s 1 2 4260 root containerd-shim /usr/local/bin/containerd-s 1 1つの Pod に相当
  • 7.
    @superbrothers  原因調査 (3/3) ▶ Ubuntu20.04/22.04 ではデフォルトで inotify instances の上限が 128 ▶ containerd は cgroup v2 使⽤時に Pod あたり2つの inotify instances を使⽤する ▶ 1ノード上に作成できる Pods 数は 110 (デフォルト)なので、64の Pod が作成されると それだけで inotify instances の上限に達してしまいエラーが発⽣する 7
  • 8.
    @superbrothers  対策 inotify instances の上限を上げる ▶値は⼗分に⼤きければよい + inotify instances は実際に作成されなければリソースを消費しない 8 # /etc/sysctl.conf fs.inotify.max_user_instances=8192 fs.inotify.max_user_watches=524288
  • 9.
    @superbrothers  で、containerd は何のために inotifyを使ってるの コンテナの OOM イベントを知るため ▶ Inotify は Linux カーネルでサポートされているファイルシステムイベント通知システムで、 ファイルシステム上のファイルやディレクトリに対するさまざまなアクション(作成、変更、 削除、移動など)に対して、カーネルがユーザースペースに通知できる ▶ OOM を含むメモリイベントを知るのに cgroup v2 の memory サブシステムで使⽤され る ”memory.events” ファイルを監視するのに inotify を使⽤している ▶ Pod あたり2つの inotify instances を使⽤するのは、 Pod が少なくともアプリケーションコンテナと pause コンテナの2つから構成されるため 9 内部的にすべての Pod に必ず存在する特殊なコンテナで、 Pod のコンテナ間で名前空間を共有するためなどに使われる
  • 10.
    @superbrothers  より詳しくは ▶ Kubernetes: cgroupv2 使⽤時に "failed to create fsnotify watcher: too many open fi les" エラーが発 ⽣する問題の対策 - Qiita 10 環境情報 ▶ OS: Ubuntu 22.04.1 LTS ▶ Kubernetes: v1.25.5 ▶ containerd: v1.6.12
  • 11.
    機械学習プラットフォームエンジニア We're hiring! https://www.preferred.jp/ja/careers/ ▶⾃由度・拡張性・使いやすさのトレードオフが取れた⼤規模機械学習プラットフォームの機能設計と開発 + 例: 機械学習ワークフローツール、実験管理ツール、GPUやMN-Core向け統合開発環境の構築 ▶ ⼤規模機械学習プラットフォームの運⽤と運⽤改善(⾃動化等) + 例: ⾃動サーバプロビジョニング、パブリッククラウド連携による運⽤効率化、 インフラ健全性の⾃動診断と保守省⼒化 ▶ ⼤規模機械学習プラットフォーム上での計算資源(GPU, MN-Coreを含む)配分の最適化 + 例: Kubernetes Schedulerの機能拡張、リソース利⽤量制限拡張の開発 ▶ 最先端の分散計算基盤技術の Proof of Concept 構築及びプラットフォームでの実⽤化 + 例: Kubernetes上での分散強化学習実⾏ツール