なんかDockerの調子が悪い→Dockerのバージョンアップで適用されるストレージドライバーが変わっていたため

Posted by 雅楽斎 on Thursday, April 21, 2022

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オプションを追加しています。

--- /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 -g /mnt/usbhdd1/var/docker-image-rootless
+ExecStart=/usr/bin/dockerd-rootless.sh -g /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