モチベーション
nerdctlコマンドを手元のマシン(Ubuntu-22.04)で稼働させたかったということで導入しました。
せっかくなのでルートレスモードで動かしてみたときの作業ログです。
前提
- Ubuntu-22.04を利用しています。
- containerdは下記手順に従い1.7.25-1をパッケージでインストールしています。
- ダウンロードするパッケージはその時の最新を指定しています。
作業の流れ
- nerdctlを入れる
- containerd-rootless-setuptool.sh installの実行
- CNI プラグインを入れる
- BuildKitを入れる
- containerd-rootless-setuptool.sh install-buildkit-containerdの実行
作業ログ
nerdctlをダウンロードします。
$ wget https://github.com/containerd/nerdctl/releases/download/v2.0.3/nerdctl-2.0.3-linux-amd64.tar.gz
$ mkdir targz
$ mv nerdctl-2.0.3-linux-amd64.tar.gz targz
$ cd targz/
展開し、バイナリを~/.local/binへと移動します。
$ tar zvxf nerdctl-2.0.3-linux-amd64.tar.gz
nerdctl
containerd-rootless-setuptool.sh
containerd-rootless.sh
$ mv containerd-rootless-setuptool.sh containerd-rootless.sh nerdctl ~/.local/bin
では、インストールしましょう。下記コマンドを実行します。が、エラーが出ます。
$ containerd-rootless-setuptool.sh install
[INFO] Checking RootlessKit functionality
[rootlesskit:parent] error: failed to setup UID/GID map: newuidmap 873607 [0 1000 1 1 100000 65536] failed: : exec: "newuidmap": executable file not found in $PATH
[ERROR] RootlessKit failed, see the error messages and https://rootlesscontaine.rs/getting-started/common/ .
エラーが出ましたが、newuidmapがないとのことですので下記でインストールします。
$ sudo apt-get install uidmap
気を取り直して再度実行してみます。
$ containerd-rootless-setuptool.sh install
[INFO] Checking RootlessKit functionality
[INFO] Checking cgroup v2
[WARNING] The cgroup v2 controller "cpu" is not delegated for the current user ("/sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service/cgroup.controllers"), see https://rootlesscontaine.rs/getting-started/common/cgroup2/
[INFO] Checking overlayfs
[INFO] Requirements are satisfied
[INFO] Creating "/home/tsuyoshi/.config/systemd/user/containerd.service"
[INFO] Starting systemd unit "containerd.service"
+ systemctl --user start containerd.service
+ sleep 3
+ systemctl --user --no-pager --full status containerd.service
● containerd.service - containerd (Rootless)
Loaded: loaded (/home/tsuyoshi/.config/systemd/user/containerd.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2025-02-24 19:28:58 JST; 3s ago
Main PID: 874120 (rootlesskit)
Tasks: 29
Memory: 23.0M
CPU: 133ms
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/containerd.service
├─874120 rootlesskit --state-dir=/run/user/1000/containerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --copy-up=/var/lib --propagation=rslave /home/tsuyoshi/.local/bin/containerd-rootless.sh
├─874138 /proc/self/exe --state-dir=/run/user/1000/containerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --copy-up=/var/lib --propagation=rslave /home/tsuyoshi/.local/bin/containerd-rootless.sh
├─874157 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 874138 tap0
└─874164 containerd
Feb 24 19:28:58 tsuyoshi-Diginnos-PC containerd-rootless.sh[874164]: time="2025-02-24T19:28:58.314123596+09:00" level=error msg="failed to load cni during init, please check CRI plugin status before setting up network for pods" error="cni config load failed: no network config found in /etc/cni/net.d: cni plugin not initialized: failed to load cni config"
Feb 24 19:28:58 tsuyoshi-Diginnos-PC containerd-rootless.sh[874164]: time="2025-02-24T19:28:58.314293435+09:00" level=info msg="Start subscribing containerd event"
Feb 24 19:28:58 tsuyoshi-Diginnos-PC containerd-rootless.sh[874164]: time="2025-02-24T19:28:58.314395273+09:00" level=info msg="Start recovering state"
Feb 24 19:28:58 tsuyoshi-Diginnos-PC containerd-rootless.sh[874164]: time="2025-02-24T19:28:58.314466363+09:00" level=info msg=serving... address=/run/containerd/containerd.sock.ttrpc
Feb 24 19:28:58 tsuyoshi-Diginnos-PC containerd-rootless.sh[874164]: time="2025-02-24T19:28:58.314508236+09:00" level=info msg="Start event monitor"
Feb 24 19:28:58 tsuyoshi-Diginnos-PC containerd-rootless.sh[874164]: time="2025-02-24T19:28:58.314546582+09:00" level=info msg=serving... address=/run/containerd/containerd.sock
Feb 24 19:28:58 tsuyoshi-Diginnos-PC containerd-rootless.sh[874164]: time="2025-02-24T19:28:58.314548659+09:00" level=info msg="Start snapshots syncer"
Feb 24 19:28:58 tsuyoshi-Diginnos-PC containerd-rootless.sh[874164]: time="2025-02-24T19:28:58.314604805+09:00" level=info msg="Start cni network conf syncer for default"
Feb 24 19:28:58 tsuyoshi-Diginnos-PC containerd-rootless.sh[874164]: time="2025-02-24T19:28:58.314621031+09:00" level=info msg="Start streaming server"
Feb 24 19:28:58 tsuyoshi-Diginnos-PC containerd-rootless.sh[874164]: time="2025-02-24T19:28:58.314663758+09:00" level=info msg="containerd successfully booted in 0.214151s"
+ systemctl --user enable containerd.service
Created symlink /home/tsuyoshi/.config/systemd/user/default.target.wants/containerd.service → /home/tsuyoshi/.config/systemd/user/containerd.service.
[INFO] Installed "containerd.service" successfully.
[INFO] To control "containerd.service", run: `systemctl --user (start|stop|restart) containerd.service`
[INFO] To run "containerd.service" on system startup automatically, run: `sudo loginctl enable-linger tsuyoshi`
[INFO] ------------------------------------------------------------------------------------------
[INFO] Use `nerdctl` to connect to the rootless containerd.
[INFO] You do NOT need to specify $CONTAINERD_ADDRESS explicitly.
では、nerdctl runしてみましょう。しかし、どうやらCNI Pluginがないとエラーになるようです。
$ nerdctl run docker.io/hello-world
docker.io/library/hello-world:latest: resolved |++++++++++++++++++++++++++++++++++++++|
index-sha256:e0b569a5163a5e6be84e210a2587e7d447e08f87a0e90798363fa44a0464a1e8: done |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:03b62250a3cb1abd125271d393fc08bf0cc713391eda6b57c02d1ef85efcc25c: done |++++++++++++++++++++++++++++++++++++++|
config-sha256:74cc54e27dc41bb10dc4b2226072d469509f2f22f1a3ce74f4a59661a1d44602: done |++++++++++++++++++++++++++++++++++++++|
layer-sha256:e6590344b1a5dc518829d6ea1524fc12f8bcd14ee9a02aa6ad8360cce3a9a9e9: done |++++++++++++++++++++++++++++++++++++++|
elapsed: 7.2 s total: 1.0 Ki (143.0 B/s)
FATA[0007] failed to verify networking settings: failed to create default network: needs CNI plugin "bridge" to be installed in CNI_PATH ("/opt/cni/bin"), see https://github.com/containernetworking/plugins/releases: exec: "/opt/cni/bin/bridge": stat /opt/cni/bin/bridge: no such file or directory
CNIプラグインが必須なので用意します。
$ cd targz
$ wget "https://github.com/containernetworking/plugins/releases/download/v1.6.2/cni-plugins-linux-amd64-v1.6.2.tgz"
$ sudo mkdir -p /opt/cni/bin/
$ cd /opt/cni/bin/
取得したパッケージを/opt/cni/bin/配下に展開します。
$ sudo tar zvxf ~/targz/cni-plugins-linux-amd64-v1.6.2.tgz
./
./ipvlan
./tap
./loopback
./host-device
./README.md
./portmap
./ptp
./vlan
./bridge
./firewall
./LICENSE
./macvlan
./dummy
./bandwidth
./vrf
./tuning
./static
./dhcp
./host-local
./sbr
以上で準備が整いましたので、再度コンテナをnerdctl runで実行してみます。
$ nerdctl run docker.io/hello-world
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/
今更ですが、nerdctlのバージョンも見ておきます
$ nerdctl -v
nerdctl version 2.0.3
続いてnerdctl buildをする際にも、依存としてBuildkitが必要らしいのでまずはそのセットアップをします。
$ cd ~/targz/
$ wget "https://github.com/moby/buildkit/releases/download/v0.20.0/buildkit-v0.20.0.linux-amd64.tar.gz"
展開します。
$ tar zvxf buildkit-v0.20.0.linux-amd64.tar.gz
bin/
bin/buildctl
bin/buildkit-cni-bridge
bin/buildkit-cni-firewall
bin/buildkit-cni-host-local
bin/buildkit-cni-loopback
bin/buildkit-qemu-aarch64
bin/buildkit-qemu-arm
bin/buildkit-qemu-i386
bin/buildkit-qemu-ppc64le
bin/buildkit-qemu-riscv64
bin/buildkit-qemu-s390x
bin/buildkit-runc
bin/buildkitd
ローカルのbinに配置します。
$ mv bin/* ~/.local/bin
ではbuildkitをインストールしてみます。
$ CONTAINERD_NAMESPACE=default containerd-rootless-setuptool.sh install-buildkit-containerd
[INFO] Creating "/home/tsuyoshi/.config/systemd/user/default-buildkit.service"
[INFO] Starting systemd unit "default-buildkit.service"
+ systemctl --user start default-buildkit.service
+ sleep 3
+ systemctl --user --no-pager --full status default-buildkit.service
● default-buildkit.service - BuildKit (Rootless)
Loaded: loaded (/home/tsuyoshi/.config/systemd/user/default-buildkit.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2025-02-24 19:39:57 JST; 3s ago
Main PID: 875190 (buildkitd)
Tasks: 10 (limit: 9042)
Memory: 7.7M
CPU: 94ms
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/default-buildkit.service
└─875190 buildkitd --oci-worker=false --containerd-worker=true --containerd-worker-rootless=true --addr=unix:///run/user/1000/buildkit-default/buildkitd.sock --root=/home/tsuyoshi/.local/share/buildkit-default --containerd-worker-namespace=default --containerd-worker-net=bridge
Feb 24 19:39:57 tsuyoshi-Diginnos-PC systemd[2796]: Started BuildKit (Rootless).
Feb 24 19:39:57 tsuyoshi-Diginnos-PC containerd-rootless-setuptool.sh[875190]: time="2025-02-24T19:39:57+09:00" level=info msg="found worker \"m6d6lyrnbolg39udz2zcavz64\", labels=map[org.mobyproject.buildkit.worker.containerd.namespace:default org.mobyproject.buildkit.worker.containerd.uuid:701277c1-05af-4e2b-95f5-8bd06ff3d6d7 org.mobyproject.buildkit.worker.executor:containerd org.mobyproject.buildkit.worker.hostname:tsuyoshi-Diginnos-PC org.mobyproject.buildkit.worker.network:cni org.mobyproject.buildkit.worker.selinux.enabled:false org.mobyproject.buildkit.worker.snapshotter:overlayfs], platforms=[linux/amd64 linux/amd64/v2 linux/amd64/v3 linux/386]"
Feb 24 19:39:57 tsuyoshi-Diginnos-PC containerd-rootless-setuptool.sh[875190]: time="2025-02-24T19:39:57+09:00" level=info msg="found 1 workers, default=\"m6d6lyrnbolg39udz2zcavz64\""
Feb 24 19:39:57 tsuyoshi-Diginnos-PC containerd-rootless-setuptool.sh[875190]: time="2025-02-24T19:39:57+09:00" level=warning msg="currently, only the default worker can be used."
Feb 24 19:39:57 tsuyoshi-Diginnos-PC containerd-rootless-setuptool.sh[875190]: time="2025-02-24T19:39:57+09:00" level=info msg="running server on /run/user/1000/buildkit-default/buildkitd.sock"
+ systemctl --user enable default-buildkit.service
Created symlink /home/tsuyoshi/.config/systemd/user/default.target.wants/default-buildkit.service → /home/tsuyoshi/.config/systemd/user/default-buildkit.service.
[INFO] Installed "default-buildkit.service" successfully.
[INFO] To control "default-buildkit.service", run: `systemctl --user (start|stop|restart) default-buildkit.service`
起動プロセスも確認できました。
$ ps auxww | grep buildkit
tsuyoshi 875190 0.1 0.4 1269852 34632 ? Ssl 19:39 0:00 buildkitd --oci-worker=false --containerd-worker=true --containerd-worker-rootless=true --addr=unix:///run/user/1000/buildkit-default/buildkitd.sock --root=/home/tsuyoshi/.local/share/buildkit-default --containerd-worker-namespace=default --containerd-worker-net=bridge
折角なので何かをビルドしてみましょう。ルートレスですのでnerdctl buildの際のsudoの指定は不要です。
$ cat Dockerfile
FROM ubuntu:24.04
RUN echo "hello world" > sample
$ nerdctl build -t helloworld .
[+] Building 35.7s (6/6) FINISHED
=> [internal] load build definition from Dockerfile 0.7s
=> => transferring dockerfile: 87B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:24.04 3.9s
=> [internal] load .dockerignore 0.5s
=> => transferring context: 2B 0.0s
=> [1/2] FROM docker.io/library/ubuntu:24.04@sha256:72297848456d5d37d1262630108ab308d3e9ec7ed1c3286a32fe09856619a782 13.5s
=> => resolve docker.io/library/ubuntu:24.04@sha256:72297848456d5d37d1262630108ab308d3e9ec7ed1c3286a32fe09856619a782 0.4s
=> => sha256:5a7813e071bfadf18aaa6ca8318be4824a9b6297b3240f2cc84c1db6f4113040 29.75MB / 29.75MB 11.0s
=> => extracting sha256:5a7813e071bfadf18aaa6ca8318be4824a9b6297b3240f2cc84c1db6f4113040 1.2s
=> [2/2] RUN echo "hello world" > sample 10.7s
=> exporting to image 4.4s
=> => exporting layers 2.3s
=> => exporting manifest sha256:5081936dce2fb7aa27abc14fc35cd901e8d79fc9787eaba954b1ff036d456f9f 0.3s
=> => exporting config sha256:454c3b8d0f6897fafd88c645c15456c8914f9b632d2c0842aa4ce79684b898e6 0.3s
=> => naming to docker.io/library/helloworld:latest 0.1s
=> => unpacking to docker.io/library/helloworld:latest 1.4s
$ nerdctl image ls helloworld
REPOSITORY TAG IMAGE ID CREATED PLATFORM SIZE BLOB SIZE
helloworld latest 5081936dce2f 12 seconds ago linux/amd64 87.61MB 29.76MB
とりあえずnerdctlが使えるところまでできたので、一旦ここまで。
参考記事
-
https://tech.virtualtech.jp/entry/2023/07/14/182708
- ほとんどこの記事の後を辿っただけです。