ArchLinux 上で Debian stretch を systemd-nspawn で立ち上げているのだが、最近 pacman -Syu したら Debian のコンテナで Java が立ち上がらなくなった。
原因
だいたいここに書いてある。
- systemd 240 で RLIMIT_NOFILE が大きくなった
- Debian の PAM では、RLIMIT_NOFILE (hard nofile)を PID 1 からコピーしている
- なので、ログインセッションなどでも RLIMIT_NOFILE が大きくなった
- ところで、Java は起動時に RLIMIT_NOFILE 分の配列を作成する
- このような環境だと RLIMIT_NOFILE が大きすぎるので OOM で落ちる
というもの。
Debian sid も systemd 241 なのに落ちなくてなぜだろうなと思ったら、そもそも hard nofile limit がそんなに大きくなかった。
大きくならないように、ビルド時にフラグをつけるようにしたらしい。
Arch で ulimit -H -s するとめちゃくちゃ大きかったので、特に触ってないのでしょう*1。
どうするか
/etc/security/limits.conf.d に hard nofile をそれなりの値に戻すような config を置く。
今回は /etc/init.d/hogehoge なスクリプトを立ち上げるだけなので大丈夫だが、 ssh でのセッションとかでも対処するなら UsePrivilegeSeparation あたりを変えないといけないらしい(未検証)。
おまけ
この事象は systemd が立ち上げるプロセスには関係せず、pam_limits.so を経由するものに関係がある。
今回、 Elasticsearch では動いたのに Jenkins で動かなかったのは何故だろうと調べていたら、Jenkins は今も /etc/init.d/jenkins なので su 経由で起動し、PAM の影響を受けるということだった。
こういうところで違いが出るんだなあ。