「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の様々な情報を確認できます。

01$ sudo nerdctl version
02Client:
03 Version:       v2.0.2
04 OS/Arch:       linux/amd64
05 Git commit:    1220ce7ec2701d485a9b1beeea63dae3da134fb5
06 buildctl:
07  Version:      v0.11.6
08  GitCommit:    2951a28cd7085eb18979b1f710678623d94ed578
09 
10Server:
11 containerd:
12  Version:      v2.0.1
13  GitCommit:    88aa2f531d6c2922003cc7929e51daf1c14caa0a
14 runc:
15  Version:      1.2.3
16  GitCommit:    v1.2.3-0-g0d37cfd4
17 
18$ sudo nerdctl info
19Client:
20 Namespace:     default
21 Debug Mode:    false
22 
23Server:
24 Server Version: v2.0.1
25 Storage Driver: overlayfs
26 Logging Driver: json-file
27 Cgroup Driver: systemd
28 Cgroup Version: 2
29 Plugins:
30  Log:     fluentd journald json-file none syslog
31  Storage: native overlayfs
32 Security Options:
33  apparmor
34  seccomp
35   Profile: builtin
36  cgroupns
37 Kernel Version:   6.8.0-48-generic
38 Operating System: Ubuntu 24.04.1 LTS
39 OSType:           linux
40 Architecture:     x86_64
41 CPUs:             16
42 Total Memory:     62.38GiB
43 Name:             rootbranch
44 ID:               1de4411a-a06e-428e-a4de-2770be07d438

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

01$ nerdctl help
02...
03Usage: nerdctl [flags]
04 
05helpers.Management commands:
06  apparmor   Manage AppArmor profiles
07  builder    Manage builds
08  container  Manage containers
09  image      Manage images
10  ipfs       Distributing images on IPFS
11...
12 
13Commands:
14  attach      Attach stdin, stdout, and stderr to a running container.
15  build       Build an image from a Dockerfile. Needs buildkitd to be running.
16  commit      Create a new image from a container's changes
17  completion  Generate the autocompletion script for the specified shell
18  compose     Compose
19  cp          Copy files/folders between a running container and the local filesystem.
20  create      Create a new container. Optionally specify "ipfs://" or "ipns://" scheme to pull image from IPFS.
21  diff        Inspect changes to files or directories on a container's filesystem
22  events      Get real time events from the server
23  exec        Run a command in a running container
24...

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

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

Rootlessコンテナ

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

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

01$ containerd-rootless-setuptool.sh install
02[INFO] Checking RootlessKit functionality
03[INFO] Checking cgroup v2
04...
05[INFO] Use `nerdctl` to connect to the rootless containerd.
06[INFO] You do NOT need to specify $CONTAINERD_ADDRESS explicitly.
07 
08# Rootless と Rootful では環境が異なっていることがあります。
09$ nerdctl version
10Client:
11 Version:       v2.0.2
12 OS/Arch:       linux/amd64
13 Git commit:    1220ce7ec2701d485a9b1beeea63dae3da134fb5
14 buildctl:
15  Version:      v0.11.6
16  GitCommit:    2951a28cd7085eb18979b1f710678623d94ed578
17 
18Server:
19 containerd:
20  Version:      v2.0.1
21  GitCommit:    88aa2f531d6c2922003cc7929e51daf1c14caa0a
22 runc:
23  Version:      1.2.3
24  GitCommit:    v1.2.3-0-g0d37cfd4
25 
26$ systemctl --user show containerd.service --property MainPID
27MainPID=2638845
28$ pstree -Asa 2638845
29systemd --system --deserialize=76
30  `-systemd --user
31      `-rootlesskit --state-dir=/run/user/1000/containerd-rootless --net=slirp4netns --mtu=65520 ...
32          |-exe --state-dir=/run/user/1000/containerd-rootless --net=slirp4netns --mtu=65520 ...
33          |   |-containerd
34          |   |   `-21*[{containerd}]
35          |   `-8*[{exe}]
36          |-slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 2638861 tap0
37          `-8*[{rootlesskit}]

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

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

01$ containerd-rootless-setuptool.sh install-bypass4netnsd
02...
03$ systemctl --user status bypass4netnsd.service
04● bypass4netnsd.service - bypass4netnsd (daemon for bypass4netns, accelerator for rootless containers)
05     Loaded: loaded (/home/utam0k/.config/systemd/user/bypass4netnsd.service; enabled; preset: enabled)
06     Active: active (running) since Sat 2024-12-28 16:18:15 JST; 2min 16s ago
07   Main PID: 2640236 (bypass4netnsd)
08      Tasks: 5 (limit: 76565)
09     Memory: 5.4M (peak: 6.3M)
10        CPU: 6ms
11     CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/bypass4netnsd.service
12             └─2640236 /usr/local/bin/bypass4netnsd
13 
14Dec 28 16:18:15 rootbranch systemd[3305]: Started bypass4netnsd.service - bypass4netnsd (daemon for bypass4netns, accelerator for rootless containers).
15Dec 28 16:18:15 rootbranch bypass4netnsd[2640236]: time="2024-12-28T16:18:15+09:00" level=info msg="SocketPath: /run/user/1000/bypass4netnsd.sock"
16Dec 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"
17Dec 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がどのくらい速いのかをテストしてみましょう。

01# Terminal-1: rootless container without bypass4netns
02$ nerdctl run --name client-wo-bypass4netns -it --rm alpine
03/ # apk add --no-cache iperf3
04...
05Executing busybox-1.37.0-r8.trigger
06OK: 7 MiB in 16 packages
07/ # iperf3 -c $HOST_IP -t 3
08...
09[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
10[  5]   0.00-1.00   sec   208 MBytes  1.74 Gbits/sec    0   68.4 KBytes
11[  5]   1.00-2.00   sec   209 MBytes  1.75 Gbits/sec    0   68.4 KBytes
12[  5]   2.00-3.00   sec   208 MBytes  1.74 Gbits/sec    0   68.4 KBytes
13- - - - - - - - - - - - - - - - - - - - - - - - -
14[ ID] Interval           Transfer     Bitrate         Retr
15[  5]   0.00-3.00   sec   624 MBytes  1.74 Gbits/sec    0             sender
16[  5]   0.00-3.00   sec   621 MBytes  1.74 Gbits/sec                  receiver
17 
18iperf Done.
19 
20# Terminal-1: rootless container with bypass4netns
21$ nerdctl run --name client-with-bypass4netns -it --rm --annotation nerdctl/bypass4netns=true alpine
22/ # apk add --no-cache iperf3
23...
24Executing busybox-1.37.0-r8.trigger
25OK: 7 MiB in 16 packages
26/ # iperf3 -c $HOST_IP -t 3
27...
28[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
29[  5]   0.00-1.00   sec  8.53 GBytes  73.2 Gbits/sec    0   1.62 MBytes
30[  5]   1.00-4.00   sec   128 KBytes   350 Kbits/sec    0   1.75 MBytes
31- - - - - - - - - - - - - - - - - - - - - - - - -
32[ ID] Interval           Transfer     Bitrate         Retr
33[  5]   0.00-4.00   sec  34.1 GBytes  73.3 Gbits/sec    0             sender
34[  5]   0.00-4.00   sec  34.1 GBytes  73.2 Gbits/sec                  receiver
35 
36iperf Done.
37 
38# Terminal-2: Host側
39$ iperf3 -s
40-----------------------------------------------------------
41Server listening on 5201 (test #1)
42-----------------------------------------------------------
43...
44[ ID] Interval           Transfer     Bitrate
45[  5]   0.00-1.00   sec   205 MBytes  1.72 Gbits/sec
46[  5]   1.00-2.00   sec   208 MBytes  1.74 Gbits/sec
47[  5]   2.00-3.00   sec   209 MBytes  1.75 Gbits/sec
48[  5]   3.00-3.00   sec   128 KBytes  1.62 Gbits/sec
49- - - - - - - - - - - - - - - - - - - - - - - - -
50[ ID] Interval           Transfer     Bitrate
51[  5]   0.00-3.00   sec   621 MBytes  1.74 Gbits/sec                  receiver
52-----------------------------------------------------------
53Server listening on 5201 (test #2)
54-----------------------------------------------------------
55...
56[ ID] Interval           Transfer     Bitrate
57[  5]   0.00-1.00   sec  8.53 GBytes  73.2 Gbits/sec
58[  5]   1.00-2.00   sec  8.49 GBytes  73.0 Gbits/sec
59[  5]   2.00-3.00   sec  8.56 GBytes  73.5 Gbits/sec
60[  5]   3.00-4.00   sec  8.55 GBytes  73.4 Gbits/sec
61[  5]   4.00-4.00   sec  4.00 MBytes  28.6 Gbits/sec
62- - - - - - - - - - - - - - - - - - - - - - - - -
63[ ID] Interval           Transfer     Bitrate
64[  5]   0.00-4.00   sec  34.1 GBytes  73.2 Gbits/sec                  receiver
65-----------------------------------------------------------
66Server listening on 5201 (test #3)
67-----------------------------------------------------------

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/

連載バックナンバー

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

「kubeshark」でKubernetesのトラフィックをリアルタイムに可視化する

2025/3/7
第13回の今回は、KubernetesのAPIトラフィックアナライザである「kubeshark」によるリアルタイムのトラフィック可視化について解説します。
仮想化/コンテナ技術解説
第12回

「OpenClarity」によるk8sワークロードの脆弱性スキャン

2025/2/21
第12回の今回は、セキュリティリスクを検出するOSSツール「OpenClarity」におけるKubernetesワークロードの脆弱性スキャンを解説します。
仮想化/コンテナ技術解説
第11回

「Longhorn」で分散ブロックストレージを簡単に管理する

2025/2/7
第11回の今回は、Kubernetes向けの分散ブロックストレージ「Longhorn」の特徴と導入方法、バックアップ・リストアの手順を解説します。

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

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

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

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