Debian 12にcontainerd+nerdctlをインストールする

今更コンテナ仮想化に挑戦します。

なぜcontainerd?

Kubernetesとか言うのがdockerをサポートしなくなったと言う話があったから……と言うのは半分で、なんか新しそうだからと言う理由です。本当はKubernetesを試してみたかったんですが複数のサーバーが必要みたいで断念しました。

containerdはDockerのコンテナ機能を抜き出したもので、またコンテナイメージには標準フォーマットがあるので他のプラットフォームでもそのまま実行可能です。それに加えセキュリティや便利な機能も追加されています。

あとなんか違いとかはNTT Tech Conference 2022の「Docker から containerd への移行」のスライドとかに詳しくあるみたいです。

containerdにもctrというコマンドインターフェースがついてきますが、nerdctlの方がDockerに似てて使いやすいとの話なのでこれも導入します。

導入

もちろん他の人がすでに解説してくれています。今回は仮想化通信さんの「containerd + nerdctlを使ってみた」の記事を元に進めます。

nerdctlはDebianのリポジトリにはないのでGithubからバイナリをダウンロードします。インストール方法はrootfulかrootlessが選べます。rootlessの方がセキュリティに良いようなので、こちらを使います。

Minimalでの失敗

(注:この章は失敗した話なので急いでいる方は読み飛ばしてください)

さて、記事のバージョンを読み替えてnerdctl-1.7.2-linux-amd64.tar.gzをダウンロードします。解凍するとcontainerdのインストールスクリプトも一緒に入ているようです。

しかしインストールスクリプトを実行すると怒られてしまいました。

[ERROR] containerd-rootless.sh needs to be present under $PATH

ドキュメントにはDockerのrootlessとほぼ同じと書いてあるだけで、たらい回しされることになります。エラー文の通り~/.local/bin$PATHに入れてあげます。

$ export PATH=~/.local/bin:$PATH

しかし以下のようにエラーが出てしまいます。

containerd-rootless-setuptool.sh: 110: rootlesskit: not found
[ERROR] RootlessKit failed, see the error messages and https://rootlesscontaine.rs/getting-started/common/ .

スクリプトを見てみるとダウンロードもインストールもする前にrootlesskitコマンドを呼び出していて、当然失敗しています。

Fullでの成功

解決策は、Fullパッケージのnerdctl-full-1.7.2-linux-amd64.tar.gzを使うということでした。そしてその解凍先を~/.local以下にします。

$ tar zxvf nerdctl-full-1.7.2-linux-amd64.tar.gz -C ~/.local

上記の通り~/.local/bin$PATHに入れ、インストールスクリプトを実行します。記事の通りnewuidmapコマンドがないと言われるのでuidmapパッケージをインストールし再度実行します。

記事ではCNI Pluginの導入と続きますがFullパッケージには同梱されているので飛ばします。

iptablesのソフトリンク

さて、一通りインストールが終わったところでテストしてみます。

$ nerdctl run docker.io/hello-world
(中略)
FATA[0004] 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="2024-01-05T07:43:02+09:00" level=fatal msg="failed to call cni.Setup: plugin type=\"bridge\" failed (add): failed to locate iptables: exec: \"iptables\": executable file not found in $PATH"

Debian 10よりiptablesの代わりにnftablesが採用されているため、iptables(の互換レイヤー)をインストールします。

# apt install iptables

しかし、iptablesはroot権限を必要とするため同様のエラーが出ると思います

色々探し回った結果、nerdctlのDiscussionによると/usr/sbin下に置かれているiptables~/.local/bin下にソフトリンクすると解決するようです。そういうものなのかという感じがしますが一応動きます。

$ ln -s /usr/sbin/iptables ~/.local/bin/iptables
$ ln -s /usr/sbin/ip6tables ~/.local/bin/ip6tables

ビルド

FullパッケージにはBuildKitも含まれているためそのままできます。

Docker で PHP + PHP-FPM × Nginx × MySQL の開発環境を構築」を元に以下をdocker-compose.ymlに書き込みます。

version: '3'

services:
  nginx:
    image: nginx:1.25.0
    ports:
      - 8000:80

ドキュメントのcomposeを元にdocker-compose upの代わりに以下のコマンドを実行します。

$ nerdctl compose up -d

その後http://localhost:8000/にアクセスし、nginxのデフォルトページが表示されていたら成功です。終了時は以下のようにします。

$ nerdctl compose down

さて、上記のリンクのイメージをビルドし直すところまで来ました。

$ nerdctl compose up -d --build
(中略)
ERRO[0000] `buildctl` needs to be installed and `buildkitd` needs to be running, see https://github.com/moby/buildkit , and `containerd-rootless-setuptool.sh install-buildkit` for OCI worker or `containerd-rootless-setuptool.sh install-buildkit-containerd` for containerd worker  

と言われてしまったので、指示通りcontainerd-rootless-setuptool.sh install-buildkit-containerdを実行します。

再度ビルドを実行すると、今度は成功しました。

コンテナの一覧

以下のコマンドでコンテナの実行状況とともに取得できます。

$ nerdctl ps -a

imagesやsaveとか

他のdockerのコマンドであるimagesやsaveなんかもdockerコマンドと同じように使えます。

最後に

もっといいやり方があったら教えてください

コメントを残す