Dockerからcontainerdへの移行 (NTT Tech Conference 2022発表レポート)

Akihiro Suda
nttlabs
Published in
14 min readApr 1, 2022

NTTの須田徳永 (共同執筆)です。NTT Tech Conference 2022 (2022/3/23)で発表した、「Dockerからcontainerdへの移行」の内容をまとめました。

https://speakerdeck.com/ktock/dockerkaracontainerdhefalseyi-xing

背景: Kubernetes 1.24は組み込み機能としてのDocker対応を打ち切る

2014年に公開された初期のKubernetesはDockerにのみ対応していましたが、2016年のKubernetes 1.5では Container Runtime Interface (CRI) と呼ばれる共通インターフェースが導入され、 CRIに対応した任意のランタイムが利用可能になりました。以来、様々なランタイムが開発されてきましたが、2022年現在では containerdCRI-O の 2つが主流です。

CRIが導入されてからも、Kubernetesに組み込まれているDocker対応機能(dockershim)が広く使われていましたが、2022年4月リリース予定のKubernetes 1.24では、dockershimがついに削除されます。

https://speakerdeck.com/ktock/dockerkaracontainerdhefalseyi-xing?slide=3

したがって、Kubernetesをdockershimで動かしてきたユーザは、containerdなどの他のランタイムへ乗り換えなければなりません。

なお、dockershim は Kubernetesの組み込み機能としては削除されますが、Mirantis 社によって cri-dockerd という外部プロジェクトとして fork され、開発が継続されています。

containerdとは

元々のcontainerd は、Dockerの下でコンテナの基本的な管理機能を提供するデーモンとして、2015年にDocker社により開発されました (2017年にCNCFに移管)。

containerdのスコープはその後拡大し、現在ではcontainerdだけで Docker (Docker Engine) の機能をほぼカバーしています。

https://speakerdeck.com/ktock/dockerkaracontainerdhefalseyi-xing?slide=7

containerdはCRIを通じてKubernetesのランタイムとして動作できるだけでなく、 docker コマンドとほぼ同じ使い勝手の nerdctl (contaiNERD CTL)コマンドもsubproject (non-core)として提供しています。 docker run に相当する nerdctl rundocker build に相当する nerdctl builddocker-compose up に相当する nerdctl compose up などの機能を取り揃えています。

containerdに移行すると新しくできること

containerd ・nerdctl は単に Docker の焼き直しではなく、多くの機能を追加しています (スライド2329):

これらの機能は全てオプショナルです。例えば、IPFSによるP2Pイメージ共有機能は、IPFSデーモン ( /usr/local/bin/ipfs )をインストールし、IPFSデーモンを起動するようにinitの設定を変更し、更に明示的に nerdctl push ipfs://... コマンドを実行しなければ有効になりません。containerd・nerdctl をインストールするだけで勝手にホストがP2Pネットワークに接続されるわけではないので、「P2P」ソフトウェアのインストールが禁止されている環境でも心配には及びません。

containerdに移行するとできなくなること

Kubernetesノードのデバッグに docker コマンドは使えなくなりますが、 nerdctl --namespace=k8s.io コマンドで代替できます。下の図では、nerdctlでビルドしたイメージをローカルノードのPodとして実行しています。イメージをレジストリにpushし、他のノードに配布することももちろん可能です ( nerdctl push )。

https://speakerdeck.com/ktock/dockerkaracontainerdhefalseyi-xing?slide=17

また、Docker REST APIに依存しているアプリケーションは動かなくなります。Docker REST API を直接呼び出さず、 docker コマンドをexecするアプリケーションについては、 nerdctl コマンドをexecするように書き換えれば動作します。

移行準備

イメージ

レジストリにpush済のDockerイメージは、containerdでもそのまま利用できます。

未pushのイメージも、docker save コマンドでtarファイルとして保存しておけば、 nerdctl load コマンドでcontainerdに移せます。

レジストリの認証情報

~/.docker/config.json や Kubernetes の imagePullSecrets はそのまま利用できます。

/etc/docker/daemon.json/etc/docker/certs.d の設定は containerd には読み込まれないので、containerd のドキュメントを参考に設定しなおす必要があります。

ログ

/var/log/pods のログ形式は異なるので、スクリプトで監視している場合はスクリプトの修正が必要です。

https://speakerdeck.com/ktock/dockerkaracontainerdhefalseyi-xing?slide=19

移行手順 (Kubernetesの場合)

マネージドKubernetesサービスの多くは、既にデフォルトのランタイムをcontainerdに変更しつつあります。ノードを作り直すだけで、簡単にDockerからcontainerdに移行できます。

非マネージド環境ではノードを作り直さなくてもkubeadm reset すれば十分ではありますが、作り直すほうが簡単なことがあります。

Google Kubernetes Engine (GKE)

GKEでは、Linuxノードについては1.19、Windowsノードについては1.21からcontainerdが既にデフォルトとなっています。

Amazon Elastic Kubernetes Service (EKS)

Amazon EKSも、Bottlerocket AMIを使う場合はcontainerd が使われます。AWS FargateでAmazon EKSを動かす場合もcontainerdが使われます。

Amazon Linux AMIやWindows AMIを用いる場合は、現在最新のAMI (Kubernetes 1.21)ではまだDockerがデフォルトとなっています。ただし、ブートストラップスクリプトに --container-runtime containerd オプションを渡すとcontainerdに切り替えることができます。

Kubernetes 1.23用のAMIからはDocker対応を打ち切り、containerdのみに対応する予定のようです。

Azure Kubernetes Service (AKS)

AKSでは、Linuxノードについては1.19からcontainerdが既にデフォルトとなっています。Windowsノードについても、1.23からcontainerdがデフォルトとなるようです。

kubeadm

Dockerとcontainerdの両方がノードにインストールされている場合、kubeadmは1.23現在ではDockerをデフォルトで選択します。

Dockerをアンインストールするか、kubeadmに明示的に --cri-socket=/run/containerd/containerd.sock オプションを渡すとcontainerdが選択されます。ただし、Windowsでは --cri-socket の値が異なります

sudo kubeadm resetsudo kubeadm join 192.168.56.120:6443 \
--cri-socket=/run/containerd/containerd.sock \
--token <省略> --discovery-token-ca-cert-hash <省略>

前述の通り、1.24からはdockershimが削除されるので、Dockerとcontainerdの両方がインストールされている場合でもcontainerdがデフォルトで選択されるようになります

移行手順 (nerdctlの場合)

Linux

バイナリアーカイブを https://github.com/containerd/nerdctl/releases からダウンロードし、 /usr/local などのパスに展開します。

安全なRootlessモードで動かす場合は、 nerdctl コマンドを実行する前に containerd-rootless-setuptool.sh install コマンドを実行します。

containerd-rootless-setuptool.sh installnerdctl run -d --name nginx -p 8080:80 nginx:alpine

macOS

containerd・nerdctl は macOS 上では直に動作しませんが、Lima (Linux Machines)を用いると、containerd・nerdctl が入ったLinux仮想マシンを簡単に起動できます。

brew install limalimactl startlima nerdctl run -d --name nginx -p 80:80 nginx:alpine

Lima は元々は nerdctl 専用の仮想マシンを立ち上げる nerdctl machine として企画していましたが、今のLimaはWindowsのWSL2に似た、汎用的なLinux仮想マシンとして利用できます。WSL2のように、ホストのファイルシステムを自動的にマウントしたり、ホストのlocalhostをゲストのlocalhostに自動的に繋げたりできます。

なお、containerd・nerdctl は Rancher Desktop にも付属しています。Rancher Desktop (macOS版)も内部的にはLimaを使っていますが、単体のLimaとは異なりGUIがついています。

Rancher Desktop

Windows

WSL2を使えば、WindowsでもLinux版のcontainerd・nerdctlを実行できます。Rancher Desktop を使うと簡単です。

nerdctlにはWindowsネイティブ版もありますが、まだ experimental です。

まとめ

Kubernetes 1.24でのdockershim削除を背景に、Docker から containerd への移行が急速に進んでいます。ログの形式など細かい違いはありますが、移行は難しくありません。従来のDockerイメージもそのまま使えます。

https://speakerdeck.com/ktock/dockerkaracontainerdhefalseyi-xing?slide=36

NTT is hiring!

私たちNTTは、 nerdctlLimaRootlessコンテナeStargz などの分野でcontainerdコミュニティに大きくコントリビュートしています。NTTでは containerd に限らず様々なオープンソースコミュニティで共に活動する仲間を募集しています。ぜひ弊社採用情報ページをご覧ください: https://www.rd.ntt/sic/recruit/

--

--