「nerdctl」で最新の「containerd」の機能を試す

2025年1月21日(火)
小松 享
第10回の今回は、コマンド操作で「containerd」を利用するためのCLIツール「nerdctl」について紹介します。

はじめに

こんにちは。3-shakeで技術顧問を務めている、うたもく(@utam0k)です。

今回は「nerdctl」について紹介します。nerdctlはDocker CLIやPodmanと同じようなコマンド操作で「containerd」を利用するためのCLIツールです。containerdはCNCF Graduatedのプロジェクトで活発に開発が進められているコンテナランタイムです。そのため、他のコンテナランタイムにはない様々な独自機能があります。

しかし、nerdctlが登場する以前は、Dockerなどではリリースサイクルの違いなどの理由から、これらの魅力的な独自機能を利用することが難しいという側面がありました。containerdが魅力的な独自機能を追加したとしても、Dockerなどの他コミュニティとの対話、パッチ、リリース待ちが必要であり、時間を要していました。過去の例を振り返ると、Rootlessコンテナ機能はその良い例と言えるでしょう。

そこで、containerdのメンテナやコミュニティを中心として開発されているのがnerdctlです。nerdctlは、どうやらメジャー、マイナーバージョンはcontainerdのリリースバージョンに合わせてリリースが行われているようです。そのため、containerdの新機能をすぐに試せます。最近の大きなリリースとして2024年11月に「containerd v2.0.0」がリリースされました。nerdctlも同日に「nerdctl v2.0.0」をリリースしています。やはり同一のコミュニティで開発されているというのは大きな利点です。

ちなみに、nerdはcontainerdから来ているようです。

nerdctlを試してみる

まずは、公式のドキュメントに従ってインストールします。以下のようにversionコマンドで自分のコンテナランタイムを取り巻く環境が分かります。また、infoコマンドでもcontainerdのserver/clientの様々な情報を確認できます。

$ sudo nerdctl version
Client:
 Version:       v2.0.2
 OS/Arch:       linux/amd64
 Git commit:    1220ce7ec2701d485a9b1beeea63dae3da134fb5
 buildctl:
  Version:      v0.11.6
  GitCommit:    2951a28cd7085eb18979b1f710678623d94ed578

Server:
 containerd:
  Version:      v2.0.1
  GitCommit:    88aa2f531d6c2922003cc7929e51daf1c14caa0a
 runc:
  Version:      1.2.3
  GitCommit:    v1.2.3-0-g0d37cfd4

$ sudo nerdctl info
Client:
 Namespace:     default
 Debug Mode:    false

Server:
 Server Version: v2.0.1
 Storage Driver: overlayfs
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Log:     fluentd journald json-file none syslog
  Storage: native overlayfs
 Security Options:
  apparmor
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version:   6.8.0-48-generic
 Operating System: Ubuntu 24.04.1 LTS
 OSType:           linux
 Architecture:     x86_64
 CPUs:             16
 Total Memory:     62.38GiB
 Name:             rootbranch
 ID:               1de4411a-a06e-428e-a4de-2770be07d438

サブコマンドの一覧を見ると、様々なコマンドがあることが分かります。Dockerで見慣れたもの、そうでないものもあると思います。nerdctlの公式のドキュメントにはDocker CLIと互換があるものの一覧が用意されています。気になる方はチェックしてみてください。

$ nerdctl help
...
Usage: nerdctl [flags]

helpers.Management commands:
  apparmor   Manage AppArmor profiles
  builder    Manage builds
  container  Manage containers
  image      Manage images
  ipfs       Distributing images on IPFS
...

Commands:
  attach      Attach stdin, stdout, and stderr to a running container.
  build       Build an image from a Dockerfile. Needs buildkitd to be running.
  commit      Create a new image from a container's changes
  completion  Generate the autocompletion script for the specified shell
  compose     Compose
  cp          Copy files/folders between a running container and the local filesystem.
  create      Create a new container. Optionally specify "ipfs://" or "ipns://" scheme to pull image from IPFS.
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  exec        Run a command in a running container
...

さて、コンテナを動かしてみましょう。

$ sudo nerdctl run --name test -it --rm alpine
/ # echo "Hello, nerdctl!"
Hello, nerdctl!
/ # exit

Rootlessコンテナ

nerdctlの注目すべき特徴として、様々なRootlessコンテナの実験的な機能が入っている点があります。Rootlessコンテナとは、一般にコンテナの実行に特権が必要ないことを指します。

公式ドキュメントに従ってセットアップを行います。実際に動かしてみると、Rootlessコンテナでのコンテナ内から外部への通信を中継する slirp4netnsなど、Rootlessコンテナに必要なツールを動かしたり、cgroupsの設定がされているのが分かると思います。

$ containerd-rootless-setuptool.sh install
[INFO] Checking RootlessKit functionality
[INFO] Checking cgroup v2
...
[INFO] Use `nerdctl` to connect to the rootless containerd.
[INFO] You do NOT need to specify $CONTAINERD_ADDRESS explicitly.

# Rootless と Rootful では環境が異なっていることがあります。
$ nerdctl version
Client:
 Version:       v2.0.2
 OS/Arch:       linux/amd64
 Git commit:    1220ce7ec2701d485a9b1beeea63dae3da134fb5
 buildctl:
  Version:      v0.11.6
  GitCommit:    2951a28cd7085eb18979b1f710678623d94ed578

Server:
 containerd:
  Version:      v2.0.1
  GitCommit:    88aa2f531d6c2922003cc7929e51daf1c14caa0a
 runc:
  Version:      1.2.3
  GitCommit:    v1.2.3-0-g0d37cfd4

$ systemctl --user show containerd.service --property MainPID
MainPID=2638845
$ pstree -Asa 2638845
systemd --system --deserialize=76
  `-systemd --user
      `-rootlesskit --state-dir=/run/user/1000/containerd-rootless --net=slirp4netns --mtu=65520 ...
          |-exe --state-dir=/run/user/1000/containerd-rootless --net=slirp4netns --mtu=65520 ...
          |   |-containerd
          |   |   `-21*[{containerd}]
          |   `-8*[{exe}]
          |-slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 2638861 tap0
          `-8*[{rootlesskit}]

ここまでは、最近のDockerでも比較的簡単にセットアップできます。nerdctlではもっと最先端なRootlessコンテナに関わる機能が利用できます。ここではbypass4netnsを動かしてみます。bypass4netnsはRootlessコンテナの「コンテナからの外向きの通信が遅い」という弱点を克服するための実験的なOSSです。仕組みや詳細についてはNTT Open SourceのブログContainer Runtime Meetup #6を参照ください。

nerdctlではbypass4netnsの環境をセットアップするスクリプトが含まれているため、簡単に環境を用意できます。

$ containerd-rootless-setuptool.sh install-bypass4netnsd
...
$ systemctl --user status bypass4netnsd.service
● bypass4netnsd.service - bypass4netnsd (daemon for bypass4netns, accelerator for rootless containers)
     Loaded: loaded (/home/utam0k/.config/systemd/user/bypass4netnsd.service; enabled; preset: enabled)
     Active: active (running) since Sat 2024-12-28 16:18:15 JST; 2min 16s ago
   Main PID: 2640236 (bypass4netnsd)
      Tasks: 5 (limit: 76565)
     Memory: 5.4M (peak: 6.3M)
        CPU: 6ms
     CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/bypass4netnsd.service
             └─2640236 /usr/local/bin/bypass4netnsd

Dec 28 16:18:15 rootbranch systemd[3305]: Started bypass4netnsd.service - bypass4netnsd (daemon for bypass4netns, accelerator for rootless containers).
Dec 28 16:18:15 rootbranch bypass4netnsd[2640236]: time="2024-12-28T16:18:15+09:00" level=info msg="SocketPath: /run/user/1000/bypass4netnsd.sock"
Dec 28 16:18:15 rootbranch bypass4netnsd[2640236]: time="2024-12-28T16:18:15+09:00" level=info msg="bypass4netns executable path: /usr/local/bin/bypass4netns"
Dec 28 16:18:15 rootbranch bypass4netnsd[2640236]: time="2024-12-28T16:18:15+09:00" level=info msg="Starting to serve on /run/user/1000/bypass4netnsd.sock"

nerdctl/bypass4netns=trueというアノテーションを付けてコンテナを起動することで、bypass4netnsを使ったコンテナが起動します。あまりにも普通に起動するので、ここではslirp4netnsと比較して、実際にbypass4netnsがどのくらい速いのかをテストしてみましょう。

# Terminal-1: rootless container without bypass4netns
$ nerdctl run --name client-wo-bypass4netns -it --rm alpine
/ # apk add --no-cache iperf3
...
Executing busybox-1.37.0-r8.trigger
OK: 7 MiB in 16 packages
/ # iperf3 -c $HOST_IP -t 3
...
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   208 MBytes  1.74 Gbits/sec    0   68.4 KBytes
[  5]   1.00-2.00   sec   209 MBytes  1.75 Gbits/sec    0   68.4 KBytes
[  5]   2.00-3.00   sec   208 MBytes  1.74 Gbits/sec    0   68.4 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-3.00   sec   624 MBytes  1.74 Gbits/sec    0             sender
[  5]   0.00-3.00   sec   621 MBytes  1.74 Gbits/sec                  receiver

iperf Done.

# Terminal-1: rootless container with bypass4netns
$ nerdctl run --name client-with-bypass4netns -it --rm --annotation nerdctl/bypass4netns=true alpine
/ # apk add --no-cache iperf3
...
Executing busybox-1.37.0-r8.trigger
OK: 7 MiB in 16 packages
/ # iperf3 -c $HOST_IP -t 3
...
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  8.53 GBytes  73.2 Gbits/sec    0   1.62 MBytes
[  5]   1.00-4.00   sec   128 KBytes   350 Kbits/sec    0   1.75 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-4.00   sec  34.1 GBytes  73.3 Gbits/sec    0             sender
[  5]   0.00-4.00   sec  34.1 GBytes  73.2 Gbits/sec                  receiver

iperf Done.

# Terminal-2: Host側
$ iperf3 -s
-----------------------------------------------------------
Server listening on 5201 (test #1)
-----------------------------------------------------------
...
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   205 MBytes  1.72 Gbits/sec
[  5]   1.00-2.00   sec   208 MBytes  1.74 Gbits/sec
[  5]   2.00-3.00   sec   209 MBytes  1.75 Gbits/sec
[  5]   3.00-3.00   sec   128 KBytes  1.62 Gbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-3.00   sec   621 MBytes  1.74 Gbits/sec                  receiver
-----------------------------------------------------------
Server listening on 5201 (test #2)
-----------------------------------------------------------
...
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  8.53 GBytes  73.2 Gbits/sec
[  5]   1.00-2.00   sec  8.49 GBytes  73.0 Gbits/sec
[  5]   2.00-3.00   sec  8.56 GBytes  73.5 Gbits/sec
[  5]   3.00-4.00   sec  8.55 GBytes  73.4 Gbits/sec
[  5]   4.00-4.00   sec  4.00 MBytes  28.6 Gbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-4.00   sec  34.1 GBytes  73.2 Gbits/sec                  receiver
-----------------------------------------------------------
Server listening on 5201 (test #3)
-----------------------------------------------------------

iperf3 の結果:

  • slirp4nets(default): 1.74 Gbits/sec
  • bypass4netns: 73.3 Gbits/sec
  • rootful: 80.3 Gbits/sec // 誌面の都合でコマンド結果は載せていません

上記の結果から一目で分かる通り、bypass4netnsはrootfulのネイティブのパフォーマンスにかなり近づいています。nerdctlであれば、このような魅力的で実験的な機能を簡単に素早く試すことができます。

他にも、nerdctlでは以下のような機能が独自にかつ簡単に使うことができます。

  • いろいろな種類のSnapshotterのlazy-pulling
  • IPFSを用いたP2Pのコンテナイメージの配布
  • FreeBSDのjailのサポート
  • 暗号化イメージ
  • KubernetesのDebuggingのための機能
  • OCI Runtime Specレベルの情報も確認できるinspectコマンド

おわりに

筆者は、今回紹介したような新しい機能をたくさん入れ込んだ実験環境があるというのは、とても良いことだと考えています。これらがあることで、 containerdと近いリリースサイクルで新しい機能をユーザーに早く提供することが可能になります。また、ユーザーに使ってもらえる環境は開発者へのモチベーションにつながると共に、フィードバックがもらえるようになるというとても良い側面もあります。

2025年はnerdctlを使って、お手元のコンテナ環境を操作してみるのはいかがでしょうか。

株式会社スリーシェイク 技術顧問
2024年7月に3-shake技術顧問として参加 。また、2023年からCNCF AmbassadorやCloud Native Community Japanのオーガナイザーを務めている。また、OSS 活動も様々行っており、Google Open Source Peer Bonusを二度受賞している。CNCF Projectのyoukiの作者。
---
スリーシェイクは、ITインフラ領域の技術力に強みをもつテクノロジーカンパニーです。SREコンサルティング事業「Sreake」では、AWS/Google Cloud/Kubernetesに精通したプロフェッショナルが技術戦略から設計・開発・運用を一貫してサポートしています。また、ノーコード型ETLツール「Reckoner」、フリーランスエンジニア特化型人材紹介サービス「Relance」、セキュリティサービス「Securify」を提供しています。
会社HP: https://3-shake.com/

連載バックナンバー

仮想化/コンテナ技術解説
第10回

「nerdctl」で最新の「containerd」の機能を試す

2025/1/21
第10回の今回は、コマンド操作で「containerd」を利用するためのCLIツール「nerdctl」について紹介します。
仮想化/コンテナ技術解説
第9回

「K8sGPT」の未来と生成AIを用いたKubernetes運用の最前線

2024/11/14
第9回の今回は、Kubernetesのトラブルシュートを生成AIで補助する「K8sGPT」について紹介します。
仮想化/コンテナ技術解説
第8回

「Kyverno Chainsaw」で宣言的なE2Eテストを実施する

2024/10/29
第8回の今回は、Kubernetes Operatorのエンドツーエンド(E2E)テストツールである「Kyverno Chainsaw」について紹介します。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています