インフラ

containerdとは?Dockerとの関係・runc/CRIの仕組みとKubernetesでの役割を解説

containerd(コンテナディー)は、コンテナの実行に特化した高レベルコンテナランタイムです。DockerやKubernetesがコンテナを動かす裏側で実際に走っている実行基盤であり、事実上の標準ランタイムとして広く使われています。この記事では、containerdがイメージの取得からコンテナ起動までのどこを担い、低レベルランタイムのruncとどう分業するのか、DockerやKubernetesとの関係(dockershim廃止後のCRI連携)、ctr・nerdctl・crictlといったCLIやsnapshotterの構成、そして1.7/2.0/2.3系のLTSとサポート期間までを一次情報で整理しました。実装者がcontainerdを直接扱うべき場面と、Docker越しに使えば足りる場面の判断軸まで示します。

まとめ:containerdの位置づけとコンテナ基盤における役割

containerdは、コンテナイメージの取得・展開、コンテナのライフサイクル管理、ストレージやネットワークの割り当てまでを受け持つ高レベルランタイムです。ただしコンテナのプロセスそのものを生成する最下層の処理は自前で行わず、OCI準拠の低レベルランタイムであるruncへ委ねます。この「高レベルはcontainerd、低レベルはrunc」という分業が、コンテナ実行基盤を理解する起点になります。なお、同じCRIランタイムでもKubernetes専用に機能を絞った選択肢としてCRI-Oとは何かもあわせて押さえると、ランタイム選定の幅が掴めます。

DockerはCLIやビルド機能を持つ上位のツール群で、その内部でコンテナを動かす部分はcontainerdが担っています。Kubernetesは1.24でDocker連携用のdockershimを削除し、いまはCRIプラグインを通じてcontainerdと直接やり取りします。つまり実装者が普段Dockerコマンドを叩いていても、Kubernetesクラスターを組んでも、下ではcontainerdが動いているのが標準構成です。本記事後半では、この基盤をどこまで直接触るべきか、AWSなどクラウド上のコンテナ運用にどう落とすかの判断まで踏み込みます。

containerdの定義とコンテナランタイムの階層構造の全体像

containerdを正しく捉えるには、コンテナランタイムが一枚岩ではなく階層に分かれている事実を押さえる必要があります。コンテナという技術そのものの仕組みを前提に、どの層をcontainerdが担うのかを分けて見ていきます。

高レベルランタイムとしてのcontainerdが受け持つ責務範囲

コンテナランタイムは、大きく高レベルと低レベルの2層に分かれます。containerdが属する高レベル側の仕事は、レジストリからのイメージpull、レイヤの展開とストレージ管理、コンテナやネットワークの構成、コンテナの起動・停止・削除といったライフサイクル制御です。CNIプラグイン経由のネットワーク設定や、後述のsnapshotterによるファイルシステム管理もこの層が束ねます。言い換えると、コンテナを「運用する」ための一通りの機能はcontainerdが受け持ち、開発者やKubernetesからの指示をrunc向けの具体的な実行命令へ翻訳する役割を負います。

runc(低レベルランタイム)へプロセス生成を委譲する分業構造

実際にLinuxカーネルのnamespaceやcgroupを設定し、コンテナのプロセスを生成する最下層の処理は、containerd自身ではなく低レベルランタイムのruncが行います。runcはOCI(Open Container Initiative)のランタイム仕様を実装した参照実装で、渡されたOCIバンドル(rootfsと設定JSON)からコンテナプロセスを起動する役割です。containerdはruncをコンテナごとに呼び出し、その生成後のプロセスをcontainerd-shimという常駐プロセスが監視し続けます。shimがdaemonとコンテナの間に入るため、containerd本体を再起動してもコンテナは動き続ける構造になっています。runc以外にも、gVisor(runsc)やKata Containersといった別の低レベルランタイムへ差し替えられる点が、OCI準拠のインターフェースを持つ強みです。

DockerからCNCFへ寄贈された経緯とOCI準拠という位置づけ

containerdは、もともとDockerエンジンの中でコンテナ実行を担っていた部分を切り出し、2017年にDocker社がCNCF(Cloud Native Computing Foundation)へ寄贈したものです。その後CNCFのGraduated(卒業)プロジェクトとなり、特定ベンダーに依存しない中立な実行基盤として維持されています。OCIのランタイム仕様・イメージ仕様の両方に準拠しているため、containerdで扱うイメージはDockerでビルドしたものと互換で、コンテナレジストリに格納したイメージをそのままpullして動かせる点が強みです。DockerとPodmanの実装差を整理したPodmanとdockerの違いの記事もあわせて読むと、ランタイム周辺の設計思想の違いが掴めます。

DockerおよびKubernetesとcontainerdの関係と連携の仕組み

containerdは単体で使うより、DockerやKubernetesの下で動く前提で理解すると全体像が繋がります。両者とcontainerdの接続点は異なるため、それぞれ分けて押さえます。

Docker内部で動くcontainerdとビルド機能との役割分担

Dockerは、イメージのビルド(Dockerfileの解釈)、CLIやAPIの提供、ネットワークやボリュームの管理といった開発者向けの機能を束ねた上位ツールです。そのうちコンテナを実際に起動・管理する中核部分はcontainerdが担当し、DockerエンジンはcontainerdをAPIで呼び出しています。docker-composeで複数コンテナを定義する仕組みも、最終的にはcontainerd経由でコンテナが起動する流れです。したがって「Dockerを使う=containerdを間接的に使う」関係にあり、開発者はcontainerdを意識せずにdockerコマンドだけで完結できます。

CRIプラグインによるkubeletとの直結とdockershim廃止の経緯

Kubernetesは、各ノードのkubeletとコンテナランタイムの間をCRI(Container Runtime Interface)という標準インターフェースでつなぎます。以前のKubernetesはCRIに未対応だったDockerを動かすため、dockershimという変換層を挟んでいましたが、この保守負担を解消するためdockershimはKubernetes 1.24(2022年5月公開)で削除されました。現在のKubernetesはcontainerdが持つCRIプラグインを通じてkubeletと直接やり取りするのが標準で、dockershimという中間層が消えた分、CPUやメモリのオーバーヘッドが減ります。この構成ではコンテナオーケストレーションとしてのKubernetesの役割と、ノード上でPodを実際に走らせるcontainerdの役割がきれいに分離されます。

containerdを構成する主要コンポーネントとバージョン体系

containerdを運用面で捉えるには、操作するためのCLI、ファイルシステムを扱うsnapshotter、そしてどのバージョンを選ぶかという3点を押さえます。ここは実装者が実際に触れる層です。

ctr・nerdctl・crictlという3つのCLIの使い分け

containerdを直接操作するCLIは目的別に分かれます。ctrはcontainerd本体に同梱されるデバッグ用の素朴なツールで、機能は限定的ですが低レベルの挙動確認に向きます。nerdctlはDocker互換のコマンド体系を持つCLIで、docker runに近い操作感でcontainerdを扱え、compose相当の機能やrootlessモードも備えているのが特徴です。crictlはCRI経由でランタイムを操作するKubernetes向けのツールで、ノード上でPodやコンテナの状態をデバッグする用途で使うツールです。日常のコンテナ操作をDockerライクに行いたいならnerdctl、Kubernetesノードの調査ならcrictl、という住み分けが実務の起点になります。

CLI 主な用途 操作感
ctr containerd本体のデバッグ 低レベル・機能限定
nerdctl 日常のコンテナ操作 Docker互換のUX
crictl Kubernetesノードの調査 CRI経由でPod単位

snapshotterとshimが担うストレージとプロセス管理

containerdはコンテナのファイルシステムをsnapshotterという差分管理の仕組みで扱います。標準はoverlayfs snapshotterで、イメージのレイヤを重ね合わせて読み書き層を最上位に置きます。2.1系ではerofs snapshotterが加わり、読み取り専用の圧縮ファイルシステムでイメージ展開の効率を高める選択肢が増えました。プロセス側では、前述のcontainerd-shimがコンテナごとに常駐し、標準入出力の中継や終了ステータスの回収を担います。この分離により、containerd daemonの更新や再起動がコンテナの稼働に影響しない設計が成り立っています。

1.7・2.0・2.3系のLTSとサポート期間を軸にしたバージョン選定

バージョンはサポート期間を軸に選びます。2026年7月時点の最新は2.3系で、2.3.3が2026-07-09に公開されています(containerd公式)。LTS(長期サポート)に指定されているのは1.7系(2023-03公開・サポートは2026年9月まで)、2.0系(2024-11公開・2027年3月まで)、2.3系(2026-04公開・2028年4月まで)で、v2.3以降は4月・8月・12月の4ヶ月周期でKubernetesのリリースに同期します。新規構築なら2.3系のLTSを選び、既存の1.7系はサポート終了が2026年9月に迫るため、Kubernetesのバージョン計画とあわせて2.x系への移行を前倒しするのが安全です。

実装者がcontainerdを直接扱うべき場面と採用の判断基準

ここは判断を言い切ります。containerdは標準基盤ですが、全員が直接触るべきものではありません。自社のコンテナ運用のどこでcontainerdを意識すべきかを、条件付きで見極めます。

containerdを直接触る場面とDockerで足りる場面の線引き

ローカル開発やCI上のビルドが中心で、コンテナをdockerコマンドで起動できていれば足りるなら、containerdを直接触る必要はありません。containerdはDockerの下で自動的に動いており、日常操作はDocker(あるいはPodman)に任せられます。containerdを直接扱う価値が出るのは、Kubernetesノードのランタイムをデバッグする、GPUやセキュアコンテナのために低レベルランタイムを差し替える、nerdctlでDocker daemonを介さない軽量な実行環境を組む、といった基盤寄りの要件が出たときです。開発者かインフラ担当かで触る深さが変わる、と割り切ると迷いません。

Kubernetesノードのランタイムとしてcontainerdを選ぶ条件

本番のKubernetesクラスターを組むなら、ノードのCRIランタイムはcontainerdが第一候補になります。dockershim廃止後の標準構成であり、マネージドKubernetesの多くもノード上でcontainerdを採用しているためです。たとえばAmazon EKSのワーカーノードでもcontainerdが動いています。こうしたAWSやクラウド上のコンテナ基盤を自社システムへ取り入れる際は、ランタイムやノード構成、運用体制の妥当性を含めて設計する必要があり、AWSを含むクラウドインフラ構築の相談窓口で、コンテナ基盤の選定から運用まで相談すると立ち上げの手戻りを減らせます。

containerdを直接運用対象にする場面で陥りやすい失敗パターン

見送るべきなのは、小規模でコンテナ数も少なく、Dockerだけで開発から本番までまわせているのに、無理にcontainerdやnerdctlへ載せ替える構成です。学習コストに見合う運用上の利得が出にくく、かえって属人化を招きます。はまりやすい失敗は3つあります。1つ目は、サポート終了間近の1.7系を放置してセキュリティ更新が受けられなくなる構成。2つ目は、Kubernetesのバージョンとcontainerdの対応関係を確認せずに片方だけ上げて非互換を踏むケース。3つ目は、ログやメトリクスをcontainerd層で取れる前提で設計せず、障害時にノードのコンテナ状態を追えない運用です。バージョンをKubernetesと同期させ、crictlでノードを調査できる体制を先に用意しておけば、containerdを基盤として安定して扱えます。コンテナ技術そのものを自社に導入すべきかの上位判断は、コンテナとはの記事で整理しています。

よくある質問

containerdの検討で実装者から多く挙がる質問を、一次情報に基づいて簡潔に整理します。

containerdとDockerの違いは何ですか?

Dockerはイメージのビルド、CLI、ネットワークやボリューム管理まで含む上位のツール群で、containerdはそのうちコンテナを実際に起動・管理する中核ランタイムです。Dockerは内部でcontainerdを呼び出しているため、両者は競合ではなく階層の異なる補完関係にあります。開発者向けの機能一式が要ればDocker、コンテナ実行基盤だけが要る場面ではcontainerd単体、という使い分けになります。

containerdとrunc(runtime)の違いは何ですか?

containerdはイメージ取得やライフサイクル管理を担う高レベルランタイム、runcはLinuxのnamespaceやcgroupを設定してコンテナプロセスを生成する低レベルランタイムです。containerdは実際のプロセス生成をrunc(OCIランタイム)へ委譲し、runcはOCIバンドルからコンテナを起動する最下層を受け持ちます。gVisorやKata Containersといった別の低レベルランタイムへ差し替えることも可能です。

Kubernetesでcontainerdを使うにはどうすればよいですか?

Kubernetes 1.24でdockershimが削除されて以降、ノードのkubeletはCRI(Container Runtime Interface)を通じてcontainerdと直接やり取りします。多くのディストリビューションやマネージドKubernetesは既定でcontainerdを採用しているため、標準的な構成では特別な設定なしにcontainerdが動く状態です。ノード上でコンテナの状態を確認するときはcrictlコマンドを使います。

ctrとnerdctlはどちらを使うべきですか?

ctrはcontainerd同梱のデバッグ用で機能が限られるため、日常のコンテナ操作にはDocker互換のUXを持つnerdctlが向きます。nerdctlはdocker runに近いコマンド体系でcontainerdを直接扱え、compose相当やrootlessモードも備えます。素の挙動を低レベルで確認したいときだけctr、通常運用はnerdctl、と使い分けるのが実務的です。

containerdはどのバージョンを選べばよいですか?

新規構築では、サポート期間が2028年4月まで確保されている2.3系のLTSが基本の選択です(2026年7月時点で2.3.3が最新)。1.7系もLTSですがサポートは2026年9月で終了予定のため、稼働中なら2.x系への移行を計画に組み込んでください。v2.3以降はKubernetesのリリースに同期して4ヶ月周期で更新されるため、Kubernetes側のバージョンと対応関係を確認しながら上げるのが安全です。

関連記事

資料請求

RELATED POSTS 関連記事