今更コンテナ仮想化に挑戦します。
なぜ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コマンドと同じように使えます。
最後に
もっといいやり方があったら教えてください