ランタイム階層を理解する
Docker / containerd / runc / CRI-O の関係をすっきり整理します。「ランタイム」と一口に言っても 3 つの階層があることを押さえます。
コンテナランタイムは 3 階層ある
「コンテナランタイム」と聞くと Docker を思い浮かべがちですが、内部的には 3 つの責務が分かれています。
| 階層 | 役割 | 代表的な実装 |
|---|---|---|
| ハイレベル(ユーザー向け) | CLI、イメージの push/pull、ボリューム・ネットワーク管理、ビルド | Docker Engine、Podman、nerdctl |
| 中レベル(デーモン) | イメージ管理、コンテナのライフサイクル、上位からの API を受ける | containerd、CRI-O |
| ローレベル(OCI ランタイム) | 実際に namespace / cgroups を設定してプロセスを起動 | runc、crun、runsc(gVisor)、kata-runtime |
Docker を使っているとき、裏では docker → containerd → runc と階層を降りて最終的にプロセスが起動しています。
Docker Engine と containerd の関係
歴史的に Docker Engine は一枚岩でしたが、2017 年頃に containerd が独立したプロジェクトとして切り出され、現在は CNCF の graduated プロジェクトです。
Docker Engine は「フロントエンド + ビルド + ネットワーク・ボリューム管理」を担い、コンテナの実体管理は containerd に委譲しています。
この分離のおかげで、
- Kubernetes は Docker を経由せず、containerd を直接使える(CRI プラグイン)
- nerdctl のような Docker CLI 互換ツールが containerd だけで動く
という選択肢が生まれました。
runc と OCI 仕様
最下層の runc は、OCI (Open Container Initiative) が定める 2 つの標準に従ってコンテナを起動します。
- OCI Runtime Spec: コンテナを起動する際の設定ファイル
config.jsonの形式と、ランタイムの振る舞いを定義 - OCI Image Spec: イメージのレイヤー構造とマニフェストの形式を定義
runc は Go で書かれた小さな実行ファイルで、containerd や cri-o などから呼び出され、実際に clone(2) + namespace 設定 + cgroups 設定 + execve(2) を行います。
代替実装として、C で書かれて起動が速い crun、ユーザー空間でシステムコールをフィルタする gVisor の runsc、軽量 VM で隔離を強化する kata-runtime などがあります。
CRI-O は何をしているのか
CRI-O は「Kubernetes のためだけに設計された中レベルランタイム」です。
Docker や containerd が汎用的に使えるのに対し、CRI-O は Kubernetes の CRI (Container Runtime Interface) 仕様を満たすことだけに絞って小さく作られています。
- クラスタは
kubelet→CRI-O→runcの順に呼び出す - OpenShift 4 系のデフォルトランタイム
- Docker CLI や docker compose は使えない(用途が違う)
Kubernetes を自分で立てる場合、containerd と CRI-O のどちらを選ぶかは好みと運用ポリシーの問題で、性能・機能面の差は小さくなっています。
どのランタイムを使っているかを確認する
ローカルマシンで実際にどのランタイムが動いているかは次のコマンドで確かめられます。
# Docker から見える実行ランタイム(runc / crun など)
docker info | grep -i runtime
# Kubernetes ノード上での CRI 実装
kubectl get nodes -o wide
# CONTAINER-RUNTIME 列に containerd / cri-o などが表示される
# containerd 側から見た実行中プロセス
sudo ctr --namespace moby containers list
「Docker か Podman か」「containerd か CRI-O か」のレイヤー違いを混ぜて議論しないように、自分が今どの階層の話をしているかを意識すると混乱を避けられます。
