はじめに
これは主にkubesprayでKubernetesクラスターを構築した人向けの記事です。
Deepfence社のThreatMapperをk8s環境で起動しようとしたところ次のようなエラーが発生して起動に失敗しました。
$ sudo kubectl -n deepfence logs deepfence-console-router-76f584f46d-pl46d
Starting router
[NOTICE] (1) : haproxy version is 2.8.5-aaba8d0
[ALERT] (1) : [haproxy.main()] Cannot raise FD limit to 1000051, limit is 65535.
なんでこんなに低いんだろうとは思いながらも検索すると、次のような記事がみつかり、/etc/containerd/cri-base.jsonの設定値を変更することで対応できました。
containerdを再起動してからPodを再作成すると無事にPodが立ち上がりました。
Starting router
[NOTICE] (1) : New worker (11) forked
[NOTICE] (1) : Loading success.
背景の調査
対応方法にはすぐに到達しましたが、後学のために少し調べておきます。
OSレベルでの設定の確認
設定方法はいくつもありますがデフォルトの状態であれば関連するのは、/etc/sysctl.conf周辺と、/etc/security/limits.confの2点だと思います。
/etc/sysctl.conf
設定については例えば次の記事をみると関連する設定が分かります。
-
Azure Kubernetes Service(AKS)ノードプールのノード構成をカスタマイズする - ファイルハンドルの制限
-
fs.file-max
-
fs.inotify.max_user_watches
-
fs.aio-max-nr
-
fs.nr_open
今回のエラーに対応するにはfs.nr_open
が十分に確保されていれば良さそうです。
確認するとこの数値はデフォルトの1048576
に設定されているので問題はなさそうです。
/etc/security/limits.conf
設定を確認すると、次のような設定だけが入っていました。
* soft nofile 5120
hardではないので変更する必要はないのですが、VSCodeかIntelliJを使った時に問題があったので増やしたような気がします。
いまとなっては65536程度に増やしても問題ないですが、これはこのままにしておきます。
結果的にOSレベルでは問題はありませんでした。
Kubesprayでの設定の確認
手動でファイルを編集するのは冪等性が維持できず良くないので、Ansibleでの設定方法について確認しておきます。
findでgrepをかけて回るとcri-base.jsonファイルに関係する設定がいくつか確認でき、パラメータで検索すると次のように初期値が設定されていることが分かります。
...
containerd_base_runtime_spec_rlimit_nofile: 65535
...
containerd_default_base_runtime_spec_patch:
process:
rlimits:
- type: RLIMIT_NOFILE
hard: "{{ containerd_base_runtime_spec_rlimit_nofile }}"
soft: "{{ containerd_base_runtime_spec_rlimit_nofile }}"
というわけでansible-playbookの"-e"オプションで設定したシステムのリミットを越えない範囲で十分に大きな数字を設定することにします。
$ ansible-playbook ... -e containerd_base_runtime_spec_rlimit_nofile=1048576 upgrade-cluster.yml
v2.24.2では-e containerd_base_runtime_spec_rlimit_nofile=1048576
を指定したことによって、/etc/containerd/cri-base.jsonの中に数値ではなく文字列として1048576が反映されたことでcontainerdが正常に稼動しないエラーになりました。sudo crictl info
が該当ノードで正常に動作しない場合にはこのファイルの修正を試みてください。
以上