TOC
なかなか腹立たしい話
いつになく腹立たしい原因からくる事象に遭遇したのでだらだらとですがまとめます。なお、rootless dockerについては以前記事にした手順で運用しています。
Dockerをrootlessに変更してrootユーザーの呪縛から開放される
結論→Dockerが使っているストレージドライバーがoverlay2からbtrfsに切り替わって既存のコンテナディレクトリでエラーを吐いていた
対応→dockerd(dockerd-rootless.sh)の引数にストレージドライバーを指定する
rootless dockerはSystemdで起動しているので、systemdのユニットファイル(~/.config/systemd/user/docker.service
)のdockerd-rootless.sh
の起動コマンドの引数にストレージドライバーの指定を追加します。私の環境ではdockerコンテナのディレクトリを別途指定しているので、-gオプションの後に--storage-driver
オプションを追加しています。
【追記】Docker23にて-g
オプションが廃止されたため、下記変更内容を--data-root
オプションに変更しています。
Dockerを23にアップグレードしたら-g(–graph)オプションが廃止されてdockerdが起動できなくなっていた
--- /home/hogehoge/.config/systemd/user/docker.service.org 2021-11-14 13:35:47.598313568 +0900
+++ /home/hogehoge/.config/systemd/user/docker.service 2022-04-20 19:14:57.287322531 +0900
@@ -5,7 +5,7 @@
[Service]
Environment=PATH=/usr/bin:/sbin:/usr/sbin:/home/hogehoge/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
-ExecStart=/usr/bin/dockerd-rootless.sh --data-root /mnt/usbhdd1/var/docker-image-rootless
+ExecStart=/usr/bin/dockerd-rootless.sh --data-root /mnt/usbhdd1/var/docker-image-rootless --storage-driver=overlay2
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
ユニットファイルを変更したら、systemdに反映させます。
$ systemctl --user daemon-reload
$ systemctl --user restart docker
対応は以上です。ここからは何が起こっていたのか振り返ります。
いつからか調子が悪い
日々使っているRaspberry Pi4のDockerコンテナがいつからか調子が悪くなってきていました。なんか動いているのか動いていないのかよくわからない。
で、コンテナは(rootless dockerの)docker-composeで起動しており、普段はRaspberry Pi4はaptでパッケージ更新してパッケージやkernelを更新して、必要があれば再起動をするという場合でもdocker-composeが自動でコンテナが起動するように設定してあるので、普段docker周りを触ることはありませんでした。
が、調子が悪いのが続くとそれはそれで困るので、重い腰を上げて調べてみました。
syslogにエラーが出ている
こんなエラーログがsyslogに出ていました。
Apr 17 09:41:32 rpi4 dockerd-rootless.sh[957961]: time="2022-04-17T09:41:32.293958521+09:00" level=info msg="skip loading plugin \"io.containerd.snapshotter.v1.aufs\"..." error="aufs is not supported (modprobe aufs failed: exit status 1 \"modprobe: FATAL: Module aufs not found in directory /lib/modules/5.13.0-1022-raspi\\n\"): skip plugin" type=io.containerd.snapshotter.v1
Apr 17 09:41:32 rpi4 dockerd-rootless.sh[957961]: time="2022-04-17T09:41:32.299179299+09:00" level=info msg="skip loading plugin \"io.containerd.snapshotter.v1.btrfs\"..." error="path /mnt/usbhdd1/var/docker-image-rootless/containerd/daemon/io.containerd.snapshotter.v1.btrfs (autofs) must be a btrfs filesystem to be used with the btrfs snapshotter: skip plugin" type=io.containerd.snapshotter.v1
Apr 17 09:41:32 rpi4 dockerd-rootless.sh[957961]: time="2022-04-17T09:41:32.305404105+09:00" level=warning msg="failed to load plugin io.containerd.snapshotter.v1.devmapper" error="devmapper not configured"
Apr 17 09:41:34 rpi4 dockerd-rootless.sh[957961]: time="2022-04-17T09:41:34.025250611+09:00" level=info msg="skip loading plugin \"io.containerd.snapshotter.v1.zfs\"..." error="path /mnt/usbhdd1/var/docker-image-rootless/containerd/daemon/io.containerd.snapshotter.v1.zfs must be a zfs filesystem to be used with the zfs snapshotter: skip plugin" type=io.containerd.snapshotter.v1
Apr 17 09:41:34 rpi4 dockerd-rootless.sh[957961]: time="2022-04-17T09:41:34.026100676+09:00" level=warning msg="could not use snapshotter devmapper in metadata plugin" error="devmapper not configured"
Apr 17 09:41:38 rpi4 dockerd-rootless.sh[957922]: time="2022-04-17T09:41:38.993008100+09:00" level=warning msg="Running modprobe bridge br_netfilter failed with message: modprobe: ERROR: could not insert 'br_netfilter': Operation not permitted\ninsmod /lib/modules/5.13.0-1022-raspi/kernel/net/bridge/br_netfilter.ko \n, error: exit status 1"
Apr 17 09:41:50 rpi4 dockerd-rootless.sh[957922]: time="2022-04-17T09:41:50.715940355+09:00" level=warning msg="Error (Unable to complete atomic operation, key modified) deleting object [endpoint 30e67a976353f6af55d028c7f4d67fcf5bfc021b9dbd971b2d2fe73465247547 c186f3c234d363704b216bb598c72803df909a61bd907e299cdb15e2b323809f], retrying...."
とりあえず、カーネルモジュールとかファイルシステム周りがおかしそうだなというのが分かったので、dockerの情報を見てみると…
$ docker info
Client:
Context: default
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Docker Buildx (Docker Inc., v0.8.1-docker)
scan: Docker Scan (Docker Inc., v0.17.0)
Server:
ERROR: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/info": dial unix /var/run/docker.sock: connect: permission denied
errors pretty printing info
Serverは上がっていません。別の環境で以前と同じ手順でrootless dockerを構築してみると…
$ docker info
(snip)
Server:
Containers: 2
Running: 2
Paused: 0
Stopped: 0
Images: 12
Server Version: 20.10.14
Storage Driver: btrfs
Build Version: Btrfs v5.10.1
Library Version: 102
(snip)
Dockerのバージョンはパッケージの更新のタイミングで変わるので良いとして、念のためrootless環境を構築した時と比較してみると…
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 20.10.10
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: false
userxattr: true
Storage Driverがいつの間にか変わってしまっています。これがどこかのdockerの更新で行われてたらそりゃ既存のコンテナ動かない訳です。何で変わっているのかよくわかりませんが、とりあえずストレージドライバーを無理やりoverlay2にすべく、検索した結果。
ストレージ・ドライバの選択 — Docker-docs-ja 19.03 ドキュメント
ストレージ・ドライバを設定するには
dockerd
コマンドで--storage-driver=<名前>
オプションを使うか、あるいは、/etc/default/docker
ファイル中のDOCKER_OPTS
行を編集します。
rootless dockerはdockerdを直接叩くのではなく/usr/bin/dockerd-rootless.sh
を呼んでいるので、ストレージドライバーの指定の仕方が同じなのか不安でしたが、試してみた結果dockerdを呼ぶ時と同様に--storage-driver=overlay2
を指定すれば結果的に大丈夫でした。今回の詰まりポイントは結果的にここだけでした。
結果、上述したsystemdのユニットファイルの変更、読み込み後にdockerの情報を確認してみると
$ docker info
Client:
Context: default
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Docker Buildx (Docker Inc., v0.8.1-docker)
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 20.10.14
Storage Driver: overlay2
Backing Filesystem: btrfs
Supports d_type: true
Native Overlay Diff: false
userxattr: true
となりました。Storage Driverはoverlay2
に変わったのは問題ないとして、Backing Filesystemがextfs
からbtrfs
に変わったのは問題ないのかと言われると問題がありそうな気はしますが、動いているので今回は見なかったことにします(指定する方法がわからないため)
一応、docker-compose up -d
のタイミングでフルビルドが走っていたように見えたので、既存のコンテナの場合はそうなっているのかもしれません。
デフォルトのストレージドライバーがbtrfsに変わったことがリリースノートに書かれていない
これが一番問題だと思うんですが、dockerのリリースノートにオプション指定しなかった場合のストレージドライバーがbtrfsに変わったことがどこにも書かれていません。
Docker Engine release notes | Docker Documentation
ほんと勘弁して…
スポンサーリンク
comments powered by Disqus