2019年3月21日木曜日

Docker コンテナが [!!!!!!] Failed to early mount API filesystems, freezing. と言って死ぬときの回避策

TL;DR

コンテナを init で起動すると死ぬ。

$ docker run -it ubuntu:16.04 init
[!!!!!!] Failed to early mount API filesystems, freezing.

--cap-add=SYS_ADMIN-v /sys/fs/cgroup:/sys/fs/cgroup:ro を付けたら行けた。

$ docker run -it --cap-add=SYS_ADMIN -v /sys/fs/cgroup:/sys/fs/cgroup:ro ubuntu:16.04 init
systemd 229 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN)
Detected virtualization vm-other.
Detected architecture x86-64.

Welcome to Ubuntu 16.04.5 LTS!

 ...

何か起きたか

ansiblesystemd 辺りをセットアップする playbook を書いたため検証しようと思ったが、わざわざ仮想マシンを起こすのもめんどくさかった。
ので、コンテナの中で systemd を、ひいては init を起こした。

docker run -it ubuntu:16.04 init

すると、 [!!!!!!] Failed to early mount API filesystems, freezing. と出力して死んだ。

何が問題だったか

どうやらコンテナ起動コマンドを init にすると、諸々の権限が足りず起動に失敗するらしい。
( 詳細までは元気が足りず調べられていない )

解決策 or 回避策

docker run するときに capability SYS_ADMIN を追加した上で、/sys/fs/cgroup を読み込み専用でマウントしてやると起動できた。

docker run -it --cap-add=SYS_ADMIN -v /sys/fs/cgroup:/sys/fs/cgroup:ro ubuntu:16.04 init

備考

最初に Google 先生に聞いてみたときには、 docker run するときに --privileged オプションを付けて特権モードで起動しろなどという恐ろしい助言が出てきたが、試してみると確かに init は起こせた。

しかし、複数のコンテナを --privileged で起動すると謎の CPU の高騰に悩まされた。
( 確か。結構昔のことなので正確に覚えていない。 )

できることなら特権を与えるなんて危険なことはしたくなかったので、もうちょっと権限を絞りたいと思って色々試したところ、↑な感じで行けた。

SYS_ADMIN よりも細かく capabilities を絞ってできるかどうかは試せていない。


参考