WSL2でRootless Docker

Posted by 雅楽斎 on Monday, April 24, 2023

TOC

まえがき

rootユーザーではないユーザーで動かすDockerであるRootless Dockerについて、Windows10とWindows11でLinuxを動かす仕組みであるWSL2上で動かします。

なお、systemdを使うので必然的にWSL2限定になることと、諸々の設定については以下の記事の続きとなります。(WSLgについてはこの記事と無関係です)

まっさらなWindows11でWSLをセットアップ)

Windows11のWSL設定続き(主にWSLgとFcitx5・Mozcによる日本語入力)

また、基本的には以前のこちらの記事と似ています。

Dockerをrootlessに変更してrootユーザーの呪縛から開放される

前準備

RootlessじゃないDockerが入っていないことを確認

$ apt-cache policy docker.io
docker.io:
  インストールされているバージョン: (なし)
  候補:               20.10.21-0ubuntu1~22.04.2
  バージョンテーブル:
     20.10.21-0ubuntu1~22.04.2 500
        500 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages
     20.10.12-0ubuntu4 500
        500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages

Rootless対応しているDockerのインストール

パッケージのインストール

現在もやっぱりUbuntuで配布しているDockerはRootless Dockerのインストーラーが付属していないので、docker.comのパッケージを使います。

# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] http://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
# apt-get update
# apt-get install uidmap docker-ce docker-ce-rootless-extras

echoコマンドでaptリポジトリを書き込む際にaptリポジトリをhttpから取得するよう変更しているので、httpsでないとという場合はhttpsへ変更します。

インストールしたそばからRootlessではないdockerが起動するので停止

# systemctl disable --now docker.service
# systemctl disable --now docker.socket

Rootless Dockerを使うユーザーでセットアップ

$ dockerd-rootless-setuptool.sh install
[ERROR] Missing system requirements. Run the following commands to
[ERROR] install the requirements and run this tool again.
[ERROR] Alternatively iptables checks can be disabled with --skip-iptables .

########## BEGIN ##########
sudo sh -eux <<EOF
# Load ip_tables module
modprobe ip_tables
EOF
########## END ##########

エラーが表示されます。ip_tablesというカーネルモジュールがないので先に進められないというエラーメッセージが表示されますが、WSL2のカーネルに限って言えば(ip_tablesモジュールはカーネルに入っているので)回避策の--skip-iptablesを付けて先に進んで大丈夫です。

というわけで、--skip-iptables引数を追加してもう一回インストールスクリプトを実行します。

$ dockerd-rootless-setuptool.sh install --skip-iptables
[INFO] Creating /home/hogehoge/.config/systemd/user/docker.service
[INFO] starting systemd service docker.service
+ systemctl --user start docker.service
+ sleep 3
+ systemctl --user --no-pager --full status docker.service
● docker.service - Docker Application Container Engine (Rootless)
     Loaded: loaded (/home/hogehoge/.config/systemd/user/docker.service; disabled; vendor preset: enabled)
     Active: active (running) since Sun 2023-04-23 14:20:52 JST; 3s ago
       Docs: https://docs.docker.com/go/rootless/
   Main PID: 659 (rootlesskit)
     CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/docker.service
             ├─659 rootlesskit --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagation=rslave /usr/bin/dockerd-rootless.sh
             ├─670 /proc/self/exe --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagation=rslave /usr/bin/dockerd-rootless.sh
             ├─688 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 670 tap0
             ├─695 dockerd
             └─714 containerd --config /run/user/1000/docker/containerd/containerd.toml --log-level info

 4月 23 14:20:52 DESKTOP-8KGOMCC dockerd-rootless.sh[695]: time="2023-04-23T14:20:52.451558069+09:00" level=info msg="Loading containers: start."
 4月 23 14:20:52 DESKTOP-8KGOMCC dockerd-rootless.sh[695]: time="2023-04-23T14:20:52.453990168+09:00" level=info msg="skipping firewalld management for rootless mode"
 4月 23 14:20:52 DESKTOP-8KGOMCC dockerd-rootless.sh[695]: time="2023-04-23T14:20:52.767457510+09:00" level=info msg="Loading containers: done."
 4月 23 14:20:52 DESKTOP-8KGOMCC dockerd-rootless.sh[695]: time="2023-04-23T14:20:52.854449593+09:00" level=warning msg="Not using native diff for overlay2, this may cause degraded performance for building images: running in a user namespace" storage-driver=overlay2
 4月 23 14:20:52 DESKTOP-8KGOMCC dockerd-rootless.sh[695]: time="2023-04-23T14:20:52.854739493+09:00" level=warning msg="WARNING: Running in rootless-mode without cgroups. To enable cgroups in rootless-mode, you need to boot the system in cgroup v2 mode."
 4月 23 14:20:52 DESKTOP-8KGOMCC dockerd-rootless.sh[695]: time="2023-04-23T14:20:52.854822393+09:00" level=info msg="Docker daemon" commit=cbce331 graphdriver=overlay2 version=23.0.4
 4月 23 14:20:52 DESKTOP-8KGOMCC dockerd-rootless.sh[695]: time="2023-04-23T14:20:52.855103193+09:00" level=info msg="Daemon has completed initialization"
 4月 23 14:20:52 DESKTOP-8KGOMCC dockerd-rootless.sh[695]: time="2023-04-23T14:20:52.912844182+09:00" level=info msg="[core] [Server #10] Server created" module=grpc
 4月 23 14:20:52 DESKTOP-8KGOMCC systemd[480]: Started Docker Application Container Engine (Rootless).
 4月 23 14:20:52 DESKTOP-8KGOMCC dockerd-rootless.sh[695]: time="2023-04-23T14:20:52.927778680+09:00" level=info msg="API listen on /run/user/1000/docker.sock"
+ DOCKER_HOST=unix:///run/user/1000//docker.sock /usr/bin/docker version
Client: Docker Engine - Community
 Version:           23.0.4
 API version:       1.42
 Go version:        go1.19.8
 Git commit:        f480fb1
 Built:             Fri Apr 14 10:32:03 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          23.0.4
  API version:      1.42 (minimum version 1.12)
  Go version:       go1.19.8
  Git commit:       cbce331
  Built:            Fri Apr 14 10:32:03 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.20
  GitCommit:        2806fc1057397dbaeefbea0e4e17bddfbd388f38
 runc:
  Version:          1.1.5
  GitCommit:        v1.1.5-0-gf19387a
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
 rootlesskit:
  Version:          1.1.0
  ApiVersion:       1.1.1
  NetworkDriver:    slirp4netns
  PortDriver:       builtin
  StateDir:         /tmp/rootlesskit4003501744
 slirp4netns:
  Version:          1.0.1
  GitCommit:        6a7b16babc95b6a3056b33fb45b74a6f62262dd4
+ systemctl --user enable docker.service
Created symlink /home/hogehoge/.config/systemd/user/default.target.wants/docker.service → /home/hogehoge/.config/systemd/user/docker.service.
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger hogehoge`

[INFO] Creating CLI context "rootless"
Successfully created context "rootless"
[INFO] Using CLI context "rootless"
Current context is now "rootless"

[INFO] Make sure the following environment variable(s) are set (or add them to ~/.bashrc):
export PATH=/usr/bin:$PATH

[INFO] Some applications may require the following environment variable too:
export DOCKER_HOST=unix:///run/user/1000//docker.sock

ちゃんと使えるか確認

ちゃんと動きそうか実行してみる

$ docker info
Client:
 Context:    rootless
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.10.4
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.17.2
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 23.0.4
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: false
  userxattr: true
 Logging Driver: json-file
 Cgroup Driver: none
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 2806fc1057397dbaeefbea0e4e17bddfbd388f38
 runc version: v1.1.5-0-gf19387a
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
  rootless
 Kernel Version: 5.15.79.1-microsoft-standard-WSL2
 Operating System: Ubuntu 22.04.2 LTS
 OSType: linux
 Architecture: x86_64
 CPUs: 8
 Total Memory: 9.633GiB
 Name: DESKTOP-XXXXXXX
 ID: 889dd80a-08fa-4d37-be63-xxxxxxxxxxx
 Docker Root Dir: /home/hogehoge/.local/share/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

WARNING: Running in rootless-mode without cgroups. To enable cgroups in rootless-mode, you need to boot the system in cgroup v2 mode.

hello-worldしてみる

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp: lookup registry-1.docker.io on 10.0.2.3:53: read udp 10.0.2.100:33355->10.0.2.3:53: i/o timeout.
See 'docker run --help'.

なぜかdockerプロセスからだけネットワークにつながらないので、名前解決できるようにWSLの設定を変更する。/etc/wsl.confに2行追加

[network]
generateResolvConf=false

設定を反映するためにコマンドプロンプトかPowerShellからWSLを停止

>wsl --shutdown

これを反映すると/etc/resolv.confが作られなくなるので、手動で/etc/resolv.confを作成

nameserver 8.8.8.8

もう一回hello-world。

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:4e83453afed1b4fa1a3500525091dbfca6ce1e66903fd4c01ff015dbcb1ba33e
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

手順としては以上で終了です。

Docker Compose

Docker Composeについては新しい機能を使うことがあまりなく、バージョンが古いdocker-composeをRootless Dockerに対して使っても問題になることが少ないので、普段はUbuntuパッケージになっているものを使っています。

# apt-get install docker-compose

ただ、最近はdockerコマンドでもdocker composeとしてbusybox方式で実行できるようにもなったので、別パッケージとしてインストールする必然性もなくなりました。使いたいバージョンに合わせて使うほうを選ぶのがいいと思います。どちらもRootless Dockerで使えます。

$ docker-compose version
docker-compose version 1.29.2, build unknown
docker-py version: 5.0.3
CPython version: 3.10.6
OpenSSL version: OpenSSL 3.0.2 15 Mar 2022
$ docker compose version
Docker Compose version v2.17.2

あとがき

以前Rootless Dockerを設定したときは環境変数DOCKER_HOSTを設定しないといけなかったりしましたが、今回試した範囲では必要ありませんでした。Rootless Docker自体も変わっているのかもしれません。

スポンサーリンク


comments powered by Disqus