🐳

Containerdとnerdctlで個人検証環境のDockerを置き換えた

2022/04/22に公開

背景

セキュアでイケてる新しい技術を使っていきたい。

「あのKubernatesはコンテナを管理するためにDockerの利用を非推奨にしているらしい😵」

「どうやら、Dockerを使わずにコンテナランタイムcontainerdを直接管理するようだ」

「containerdに含まれるnerdctlを使えばDocker不要実験的最新機能を利用可能だとのこと」

「nerdctlはDocker風のUI/UXを採用しており、学習コストは低そうだ」

「イケてるね😊」

ということで、今回は自分の検証環境で使っていたDockerをcontainerdnerdctlで置き換えてみることにしました。

思い立ったきっかけは、NTT Tech Conference 2022の発表資料を読んだことです。

https://www.slideshare.net/KoheiTokunaga/dockercontainerd

containerdとnerdctlでコンテナでは、いろいろな実験的最新機能が使えるとのことだったのですが、今回は私が自分の検証環境での利用において特に魅力に感じた以下の2つの最新機能も導入していきます。

  • 高速なイメージPull(eStargz)
  • 高速rootless

containerdおよびnerdctlのインストール

  1. nerdctlレポジトリのReleasesから
    nerdctl-full-<VERSION>-<OS>-<ARCH>.tar.gzをダウンロードする。
wget https://github.com/containerd/nerdctl/releases/download/v0.18.0/nerdctl-full-0.18.0-linux-amd64.tar.gz
  1. nerdctlのバイナリを/usr/local/binに展開する。
sudo tar Cxzvvf /usr/local/bin nerdctl-0.18.0-linux-amd64.tar.gz
  1. rootlessモードでcontainerdをインストールする。
containerd-rootless-setuptool.sh install
インストール成功時の出力例
[INFO] Checking RootlessKit functionality
[INFO] Checking cgroup v2
[WARNING] Enabling cgroup v2 is highly recommended, see https://rootlesscontaine.rs/getting-started/common/cgroup2/
[INFO] Checking overlayfs
[INFO] Requirements are satisfied
[INFO] Creating "/home/ubuntu/.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/ubuntu/.config/systemd/user/containerd.service; disabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-04-14 00:56:36 UTC; 3s ago
   Main PID: 13328 (rootlesskit)
     CGroup: /user.slice/user-1000.slice/user@1000.service/containerd.service
             tq13328 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 /usr/local/bin/containerd-rootless.sh
             tq13337 /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 /usr/local/bin/containerd-rootless.sh
             tq13351 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 13337 tap0
             mq13359 containerd

Apr 14 00:56:37 ip-*-*-*-* containerd-rootless.sh[13359]: time="2022-04-14T00:56:37.222219722Z" 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"
Apr 14 00:56:37 ip-*-*-*-* containerd-rootless.sh[13359]: time="2022-04-14T00:56:37.248244884Z" level=info msg="Start subscribing containerd event"
Apr 14 00:56:37 ip-*-*-*-* containerd-rootless.sh[13359]: time="2022-04-14T00:56:37.248662658Z" level=info msg="Start recovering state"
Apr 14 00:56:37 ip-*-*-*-* containerd-rootless.sh[13359]: time="2022-04-14T00:56:37.248982202Z" level=info msg="Start event monitor"
Apr 14 00:56:37 ip-*-*-*-* containerd-rootless.sh[13359]: time="2022-04-14T00:56:37.249220204Z" level=info msg="Start snapshots syncer"
Apr 14 00:56:37 ip-*-*-*-* containerd-rootless.sh[13359]: time="2022-04-14T00:56:37.249496337Z" level=info msg="Start cni network conf syncer for default"
Apr 14 00:56:37 ip-*-*-*-* containerd-rootless.sh[13359]: time="2022-04-14T00:56:37.249687630Z" level=info msg="Start streaming server"
Apr 14 00:56:37 ip-*-*-*-* containerd-rootless.sh[13359]: time="2022-04-14T00:56:37.250648286Z" level=info msg=serving... address=/run/containerd/containerd.sock.ttrpc
Apr 14 00:56:37 ip-*-*-*-* containerd-rootless.sh[13359]: time="2022-04-14T00:56:37.250903736Z" level=info msg=serving... address=/run/containerd/containerd.sock
Apr 14 00:56:37 ip-*-*-*-* containerd-rootless.sh[13359]: time="2022-04-14T00:56:37.251110841Z" level=info msg="containerd successfully booted in 0.095489s"
+ systemctl --user enable containerd.service
Created symlink /home/ubuntu/.config/systemd/user/default.target.wants/containerd.service → /home/ubuntu/.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 ubuntu`
[INFO] ------------------------------------------------------------------------------------------
[INFO] Use `nerdctl` to connect to the rootless containerd.
[INFO] You do NOT need to specify $CONTAINERD_ADDRESS explicitly.

BuildKitの有効化

Dockerfileをビルドするためには、以下のコマンドにてBuildKitを有効化する必要があります。

CONTAINERD_NAMESPACE=default containerd-rootless-setuptool.sh install-buildkit-containerd

実験的機能: 高速なイメージPull(eStargz)

イメージPullの高速化(Lazy pulling)を可能とするための手順を進めていきます。
https://github.com/containerd/nerdctl/blob/master/docs/rootless.md#stargz-snapshotter

  1. Stargz Snapshotterを有効化する。
containerd-rootless-setuptool.sh install-stargz
  1. containerdの以下の内容でconfigを用意する。
    /run/user/10001000には、nerdctlを利用するユーザのUIDに置き換えてconfigを配置します。
~/.config/containerd/config.toml
[proxy_plugins]
  [proxy_plugins."stargz"]
      type = "snapshot"
# NOTE: replace "1000" with your actual UID
      address = "/run/user/1000/containerd-stargz-grpc/containerd-stargz-grpc.sock"
UID確認方法
$ echo $UID
1000
  1. containerdを再起動してconfig変更を反映する。
systemctl --user restart containerd.service
  1. 高速なイメージPullの実行する。
    以下の--snapshotter=stargzオプションで高速なイメージPullを実行することができます。
nerdctl run --snapshotter=stargz ghcr.io/stargz-containers/python:3.10-esgz python -c "print('hello')"

高速rootless

特権無しでコンテナを動かすことができるRootlessモードには、セキュリティの面での利点がありますが、特権有りのRootfulモードと比較して、コンテナ外との通信速度が遅いという欠点があるそうです。

bypass4netnsを使うことで、Rootlessの対コンテナ外通信速度がRootfulよりも早くなります。

  1. bypass4netnsを有効化する。
containerd-rootless-setuptool.sh install-bypass4netnsd
  1. 高速rootless機能を使ってコンテナを起動する。
    以下の--label nerdctl/bypass4netns=trueオプションで高速なイメージPullを実行することができます。
nerdctl run --label nerdctl/bypass4netns=true ghcr.io/stargz-containers/python:3.10-esgz python -c "print('hello')"

環境

Ubuntu 20.04.3 LTS (x86_64) on AWS

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.3 LTS"
$ uname -a
Linux ip-172-18-1-111 5.11.0-1022-aws #23~20.04.1-Ubuntu SMP Mon Nov 15 14:03:19 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

使ってみた感想

containerdとnerdctlを個人の検証環境で使い始めて今のところは、Dockerと比べて優れた体験をしているような感覚はありません。

もうちょっと触ってみて感じることがあれば、また記事にしていこうと思います。

Discussion