WSL2にDocker代替のNerdCtl(containerd)を入れてみる(2023)
Rancher Desktop 重くね?
関連記事:
WSL2にDocker代替のNerdCtl(containerd)を入れてみる
ポッドマンが倒せないシリーズ過去記事
ポッドマンが倒せないシリーズでPodmanについてはいろいろやった。
自宅の環境は十分整ったのだが、
どうにも会社の環境に合わない。
会社の環境はDockerで作ったものの、
PCリソースが厳しくて代替策を探しているのだが、
Podmanでは認証周りが解決できなかった。
(時間的に断念)
代わりとなるとRancher Desktopだが、
( ゚Д゚) Rancher Desktop 重くね?
実は以前Rancher Desktopの記事を書いていたが、
あんまり使い物にならなそうだったので公開しなかった。
ならRancher Desktopの標準であるcontainerdを使えばいいか。
ということでWSLにcontainerdを入れてみる。
以前の記事ではとりあえず試した程度だったので、
改めてやり直そう。
ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪
------------------- ↓ 本題はここから ↓-------------------
準備
クライアント側を用意
以下を参照のこと
containerdをインストール
dockerリポジトリにcontainerdのパッケージ containerd.io
があるのでそれを使う。
インストール方法はdockerのマニュアル通り。
sudo dnf remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine
sudo dnf -y install dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
sudo dnf install -y containerd.io
sudo chmod u+s $(which newuidmap)
sudo chmod u+s $(which newgidmap)
sudo systemctl enable --now containerd
containerd --version
containerd containerd.io 1.6.21 3dce8eb055cbb6872793272b4f20ed16117344f8
runc --version
runc version 1.1.7
設定ファイルの初期状態がいまいちなので、
バックアップを取りつつ初期値に変える
sudo mv /etc/containerd/config.toml /etc/containerd/config.toml.origin
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
nerdctlのインストール
containerd用docker互換コマンドnerdctlをインストールする。
rootlessモード利用を想定しているので、
rootlessコマンドなどを含むフル版を使用
以下のページより最新のFULL版を取得
mkdir -p ~/.local/src && cd ~/.local/src
curl -LO https://github.com/containerd/nerdctl/releases/download/v1.3.1/nerdctl-full-1.3.1-linux-amd64.tar.gz
tar xzfz nerdctl-full-1.3.1-linux-amd64.tar.gz -C ~/.local/
~/.local/bin
を$PATHに通しておく。
source ~/.bashrc
which runc
/home/dozo/.local/bin/runc
CNI Pluginインストール
CNIプラグインのパッケージをインストール
sudo dnf install containernetworking-plugins -y
cniプラグイン設定を追加する。
無効化する行があるのでコメントアウトし、
bin_dir
にパスを設定
[plugins."io.containerd.grpc.v1.cri".cni]
+ bin_dir = "/usr/libexec/cni"
contenerdを再起動
sudo systemctl restart containerd
containerd config dump | grep -i bin_dir -B 1
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/usr/libexec/cni"
rootlessモード化
containerdをrootlessで動くようにする。
また、どのみち必要になるbuildkitも使えるようにしておく。
~/.local/bin/containerd-rootless-setuptool.sh install
systemctl --user status containerd
● containerd.service - containerd (Rootless)
Loaded: loaded (/home/dozo/.config/systemd/user/containerd.service; enabled; preset: disabled)
Drop-In: /usr/lib/systemd/user/service.d
└─10-timeout-abort.conf
Active: active (running) since Sun 2023-05-14 09:52:22 JST; 19min ago
Main PID: 82 (rootlesskit)
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/containerd.service
~/.local/bin/containerd-rootless-setuptool.sh install-buildkit
~/.local/bin/containerd-rootless-setuptool.sh install-buildkit-containerd
systemctl --user status buildkit
● buildkit.service - BuildKit (Rootless)
Loaded: loaded (/home/dozo/.config/systemd/user/buildkit.service; enabled; preset: disabled)
Drop-In: /usr/lib/systemd/user/service.d
└─10-timeout-abort.conf
Active: active (running) since Sun 2023-05-14 10:05:13 JST; 5min ago
Main PID: 501 (buildkitd)
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/buildkit.service
└─501 buildkitd
動作確認
mkdir ~/airflow && cd ~/airflow
curl -LO https://raw.githubusercontent.com/bitnami/containers/main/bitnami/airflow/docker-compose.yml
nerdctl compose up -d
起動まで少しかかるのでログをみる
nerdctl compose logs -f
・・・
airflow-scheduler_1 | ____________ _____________
airflow-scheduler_1 | ____ |__( )_________ __/__ /________ __
airflow-scheduler_1 |____ /| |_ /__ ___/_ /_ __ /_ __ \_ | /| / /
airflow-scheduler_1 |___ ___ | / _ / _ __/ _ / / /_/ /_ |/ |/ /
airflow-scheduler_1 | _/_/ |_/_/ /_/ /_/ /_/ \____/____/|__/
・・・
airflow-worker_1 |[2023-05-14 01:35:34,694: INFO/MainProcess] celery@airflow-worker ready.
起動したっぽい
airflow login
(^_-)-☆ 動いた!
思ったよりうまくいったか。
参考文献
------------------- ↓ 後書きはここから ↓-------------------
cgroupをv2に変更
rootlessだとcgroupをv2にしろと言われた。
nerdctl info
WARNING: Running in rootless-mode without cgroups. To enable cgroups in rootless-mode, you need to boot the system in cgroup v2 mode.
サポート状態を確認
mount -l | grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,size=4096k,nr_inodes=1024,mode=755)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
kernelのパラメータを調整するらしい。
まずはwsl事態の設定から
kernelCommandLine=systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all
fstabを調整
echo 'cgroup2 /sys/fs/cgroup cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate 0 0' | sudo tee -a /etc/fstab
sudo mount -a
システム自体を再起動する
exit
wsl --shutdown
wsl -d fedora38
状態を確認
mount -l | grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (rw,nosuid,nodev,noexec,relatime,mode=755)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
fedoraには update-grub
コマンドがないので、
grubby
で代用
sudo dnf install -y grubby
sudo printf "GRUB_CMDLINE_LINUX=\"systemd.unified_cgroup_hierarchy=1\"\n" | sudo tee /etc/default/grub
sudo grub2-set-default 2
sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"
exit
wsl -t Fedora38
wsl -d Fedora38
ランタイムをcrunに変更
sudo dnf install crun
crun --version
crun version 1.8.4
which crun
/usr/bin/crun
[plugins."io.containerd.grpc.v1.cri".containerd]
- default_runtime_name = "runc"
+ default_runtime_name = "crun"
+ [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.crun]
+ runtime_type = "io.containerd.runc.v2"
+ [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.crun.options]
+ BinaryName = "/usr/bin/crun"
+ SystemdCgroup = true
systemctl --user restart containerd
最新版インストール
containerdの最新版を使うにはバイナリを直接使う流れっぽい。
なのでバイナリインストール方法も記載しておく。
バイナリ版インストール
最新版のパッケージはなさそうなので、
Githubから直接ダウンロード。
rootで扱うので /usr/local/
配下に配置する。
以下のページより最新版を取得
cd /usr/local/src/
sudo curl -LO https://github.com/containerd/containerd/releases/download/v1.7.1/containerd-1.7.1-linux-amd64.tar.gz
sudo tar xvfz ./containerd-1.7.1-linux-amd64.tar.gz -C /usr/local/
containerd --version
containerd github.com/containerd/containerd v1.7.1 1677a17964311325ed1c31e2c0a3589ce6d5c30d
サービスを登録
sudo curl -LO https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
sudo cp containerd.service /usr/lib/systemd/system/
sudo systemctl enable --now containerd
systemctl status containerd
● containerd.service - containerd container runtime
Loaded: loaded (/usr/lib/systemd/system/containerd.service; enabled; preset: disabled)
Drop-In: /usr/lib/systemd/system/service.d
└─10-timeout-abort.conf
Active: active (running) since Sat 2023-05-13 08:12:38 JST; 13s ago
コンテナランタイムをインストール
コンテナランタイムのruncをインストール。
以下のページより最新版を取得
sudo curl -LO https://github.com/opencontainers/runc/releases/download/v1.1.7/runc.amd64
sudo install -m 755 runc.amd64 /usr/local/sbin/runc
runc --version
runc version 1.1.7
commit: v1.1.7-0-g860f061b
spec: 1.0.2-dev
go: go1.20.3
libseccomp: 2.5.4
CNI pluginsをインストール
以下のページより最新版を取得
sudo mkdir -p /opt/cni/bin
sudo curl -LO https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz
sudo tar xzvf cni-plugins-linux-amd64-v1.1.1.tgz -C /opt/cni/bin
初期設定値を配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
トラブルシューティング
listen tcp 0.0.0.0:80: bind: permission denied
1024以下のポートは権限ないとダメよ
FATA[0000] failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error running hook #0: error running hook: exit status 1, stdout: , stderr: time="2023-05-14T10:17:52+09:00" level=fatal msg="failed to expose ports in rootless mode: cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or set CAP_NET_BIND_SERVICE on rootlesskit binary, or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission denied"
Failed to write to log, write /home/dozo/.local/share/nerdctl/1935db59/containers/default/a1ca3b639b61e8ed1c438c627e267de171daf38d6428bcf6b3c07967ee6eff1d/oci-hook.createRuntime.log: file already closed: unknown
FATA[0049] error while creating container discourse_discourse_1: exit status 1
sysctlで設定
(または /etc/sysctl.conf
に記述)
sudo sysctl net.ipv4.ip_unprivileged_port_start=80
RootlessKit failed, rootlesskit: command not found
rootlesskitが見つからない問題
~/.local/bin/containerd-rootless-setuptool.sh install
[INFO] Checking RootlessKit functionality
/home/dozo/.local/bin/containerd-rootless-setuptool.sh: line 111: rootlesskit: command not found
[ERROR] RootlessKit failed, see the error messages and https://lesscontaine.rs/getting-started/common/ .
コマンドへのパスが通っていないのが原因
export PATH=~/.local/bin/:$PATH
newuidmap権限問題
例のあれ
[rootlesskit:parent] error: failed to setup UID/GID map: newuidmap 3653 [0 1000 1 1 524288 65536] failed: newuidmap: write to uid_map failed: Operation not permitted
: exit status 1
[ERROR] RootlessKit failed, see the error messages and https://rootlesscontaine.rs/getting-started/common/ .
コマンドの権限不足
sudo chmod u+s $(which newuidmap)
sudo chmod u+s $(which newgidmap)
コンテナ内のネットワークから外に出られない問題
VPNの時と同じような問題が。
nerdctl compose up -d
・・・
INFO[0010] trying next host error="failed to do request: Head \"https://registry-1.docker.io/v2/bitnami/airflow-worker/manifests/2\": dial tcp: lookup registry-1.docker.io on 10.0.2.3:53: read udp 10.0.2.100:45252->10.0.2.3:53: i/o timeout" host=registry-1.docker.io
FATA[0010] failed to resolve reference "docker.io/bitnami/airflow-worker:2": failed to do request: Head "https://registry-1.docker.io/v2/bitnami/airflow-worker/manifests/2": dial tcp: lookup registry-1.docker.io on 10.0.2.3:53: read udp 10.0.2.100:45252->10.0.2.3:53: i/o timeout
コンテナ内のネットワークのから外部に出るときの名前解決ができないのが原因
コンテナ内部の /etc/resolv.conf
を調整する
containerd-rootless-setuptool.sh nsenter bash
printf "nameserver 1.1.1.1\n" | tee /etc/resolv.conf
Discussion