Ubuntu22.04でNFS_Homeで rootless containerdを試す
Posted:
背景
私はNFS homeを利用している。NFS上にコンテナを置けないトラブルへのTIPSについて残しておく。 またログが~/.local/share/nerdctl配下に書き出されるが、NFS上にログが書き出されると非常に重くなってしまうので別の場所をしていするようにした
chown ができない、というエラーが出る
error: failed to solve: failed to compute cache key: mount callback failed on /var/lib/containerd/tmpmounts/containerd-mount2455064670: failed to Lchown "/var/lib/containerd/tmpmounts/containerd-mount2455064670/etc/gshadow" for UID 0, GID 42: lchown /var/lib/containerd/tmpmounts/containerd-mount2455064670/etc/gshadow: operation not permitted: unknown
NFSの場合、rootlessが動作しない、ようだ
rootless containerdはデフォルトでホームディレクトリ配下を使用するが、私がNFS Homeだったので動作しなかった。
Redhatのエントリが参考になる。 Rootless Podman and NFS
Why doesn’t Podman support storage on NFS?
The use case that does not work well is having the container image store reside on an NFS mount point.
ンテナイメージをNFS上に置くのは良くないらしい。
The NFS protocol has no concept of user namespaces and has no way to know that the process running as UID 1000 is in one.
The NFS server also has no way of knowing that the client process has DAC_OVERRIDE for the user namespace and that UID 100059 is mapped into the same user namespace.
In other words, the chance of this information being known by NFS is slim at best.
NFSサーバ側はクライアント側で DAC_OVERRIDE しようとしているかなど分からない(NFSはサポートしていない機能なので仕方がない)
解決策としては2つのアプローチが紹介されている。
- ~/.config/containers/storage.conf を書き換えてストレージのディレクトリを変更する
- ディスクイメージのファイルを作成し ~/.local/share/containers にマウントする
[1]の方法が使えないか確認してみた。私の場合、 ~/.config/containerd/storage.conf は存在しなかったので新規作成の形だった。
[storage]
driver = "overlay"
runroot = "/run/user/1000"
graphroot = "/var/tmp/myuser/containers/storage
ブログが2019年の記事(今は2024年)だからかcontainerdを再起動してもうまく行かない(/var/tmp/503というディレクトリが作成されない)
[1]ではなく[2]の方法を試す。 下記、<myuser> のディレクトリのパスは修正する必要がる。
truncate -s 10g /home/myuser/xfs.img
mkfs.xfs -m reflink=1 /home/myuser/xfs.img
mount /home/myuser/xfs.img /home/myuser/.local/share/containers
上記だとnerdctlでコンテナがビルドできた。
別のディスク領域でコンテナイメージを置こうとしたところUbuntuでapparmorの制限がかかってしまう模様
NFS上のディスクイメージをマウントしてコンテナイメージを置くより、SSD上に置いた方が高速だよね、と思って試したらAppArmorの制限に引っかかった。
デバック中に使ったcontainerd用の調査用コマンドctrはこちらにまとめた
ログが書き出される場所を変えたい
私がコンテナ内のシェルを起動した場合、下記のコマンドが起動していた。
exampleuser 17383 4971 0 23:14 pts/4 00:00:00 /bin/bash /mnt/nfs/home/exampleuser//workspace/git/github.com/exampleuser/cli-tool-docker/rootless-container.bash
exampleuser 17385 17383 6 23:14 pts/4 00:00:00 /usr/local/bin/nerdctl run --network host --rm --init -it --volume /mnt/nfs/home/exampleuser/:/mnt/nfs/home/exampleuser/ --env HOME=/mnt/nfs/home/exampleuser/ -w /mnt/nfs/home/exampleuser/ cli-tool-docker fish -l
exampleuser 17404 17385 0 23:14 pts/4 00:00:00 /usr/local/bin/nerdctl _NERDCTL_INTERNAL_LOGGING /mnt/nfs/home/exampleuser/.local/share/nerdctl/1935db59
exampleuser 17423 1066 0 23:14 ? 00:00:00 /usr/local/bin/containerd-shim-runc-v2 -namespace default -id 1282772d592412eb396048d1d5ba8f8fa79a509929c3410f2dc857adbeec096e -address /run/containerd/containerd.sock
exampleuser 17449 17423 0 23:14 pts/0 00:00:00 /sbin/tini -- fish -l
上記のうち、下記のようなプロセスがロギングを行っている模様。
コンテナが固まってしまう症状に悩んでいるのだが、固まっている際のプロセスの状況は下記だった。
exampleuser 5308 4971 0 23:04 pts/2 00:00:00 /bin/bash /mnt/nfs/home/exampleuser//workspace/git/github.com/exampleuser/cli-t
ool-docker/rootless-container.bash
exampleuser 5311 5308 0 23:04 pts/2 00:00:00 /usr/local/bin/nerdctl run --network host --rm --init -it --volume /net/192.0.2.1
0/homes/exampleuser/:/mnt/nfs/home/exampleuser/ --env HOME=/mnt/nfs/home/exampleuser/ -w /mnt/nfs/home/exampleuser/ cli-tool-dock
er fish -l
exampleuser 5341 5311 0 23:04 pts/2 00:00:00 [nerdctl] <defunct>
exampleuser 5362 1066 0 23:04 ? 00:00:00 /usr/local/bin/containerd-shim-runc-v2 -namespace default -id aaeedfa8f22ef2af379ee
1528830c455327b6057b9944ba12035bf0a8e300eec -address /run/containerd/containerd.sock
exampleuser 5384 5362 0 23:04 pts/0 00:00:00 /sbin/tini -- fish -l
ロギングのプロセスが <defunct> になっているような…?
/usr/local/bin/nerdctl _NERDCTL_INTERNAL_LOGGING /mnt/nfs/home/exampleuser/.local/share/nerdctl/1935db59
_NERDCTL_INTERNAL_LOGGING とはなんだろうか…?
/usr/bin/nerdctl _NERDCTL_INTERNAL_LOGGING process consumes lots of file description · Issue #2441 · containerd/nerdctl なにかロギングで使うようだ。そしてファイルディスクリプタをすごく消費するらしい。 私のNASサーバの性能はあまり高くない…
nerdctlのロギングのオプションを確認してみる。
–log-driverというオプションが存在する。デフォルトはjson-file。
そしてjson-fileの場合、更に --log-opt=log-path=<LOG-PATH> という設定が可能らしい。
そして変更してみたが、効果はないようだ。このロギングのプロセスが存在する。
(2024/03時点での検証なので将来的には実装が変わるかもしれない)
この辺の実装は将来的に改善される可能性があるが、私はひとまずbindマウントを行い、NFS homeではなくローカルのディスクをマウントするようにした。 systemdのunitファイルを修正する。ExecStartPreは、実際に実行したいコマンドの前に行うコマンドを記述できる。
ExecStartPre=sudo mount --bind /mnt/append-disk/containerd/log /mnt/nfs/home/exampleuser/.local/share/nerdctl/