低レイヤのランタイム - runc / CRI-O
runc は OCI Runtime Spec の参照実装、CRI-O は Kubernetes 向けに CRI を最小実装したランタイム。コンテナスタックの最下層と Kubernetes 向け層を担う。
概念図
構文
runc: OCI Runtime Spec の参照実装
runc は OCI(Open Container Initiative)の Runtime Specification に対する参照実装で、Go と一部 C で書かれた小さなバイナリです。
役割は極めて限定的で、ルートファイルシステムと config.json(OCI Runtime Spec が規定する JSON)を受け取り、namespace、cgroups、capabilities、seccomp を設定してプロセスを起動するところまでを担当します。
イメージの pull やレイヤ管理、ネットワーク構築は一切行いません。
containerd、Podman、CRI-O といった上位のランタイムがそれぞれの事情でイメージを展開し、最終的に runc にプロセス起動を依頼します。
runc 自体は単体で使われるより、スタックの最下層の共通部品として存在する位置づけです。
CRI-O: Kubernetes 向けに最小化された実装
CRI-O は Kubernetes の Container Runtime Interface だけを満たすことを目的に作られたランタイムで、Red Hat 主導で開発されています。
kubelet が必要とする機能(Pod の作成、コンテナ起動、ログ取得など)以外を削ぎ落とし、内部では OCI 互換の低レイヤランタイム(通常は runc または crun)を呼び出します。
同じ Kubernetes 向けランタイムとしては containerd が最大シェアですが、CRI-O は OpenShift などの Red Hat 系プラットフォームで採用例が多いのが特徴です。
「Kubernetes 専用」であることが明確で、Docker 由来の機能を抱えない分コードベースが小さく、セキュリティ更新の追跡が容易という設計思想です。
階層図(CLI → 中 → 低レイヤ)
コンテナスタックは概ね 3 層で整理できます。
最上位は利用者が触る CLI や API で、docker、podman、kubectl(経由で kubelet)などが該当します。
中レイヤはイメージ管理とライフサイクル制御を担当し、containerd、CRI-O、dockerd などが位置します。
最下層は OCI 仕様に沿ってプロセスを起動する runc、crun、youki などです。
各層は OCI Image Spec と OCI Runtime Spec によって互換性が保たれているため、組み合わせを比較的自由に差し替えられます。
たとえば「CLI は nerdctl、中レイヤは containerd、低レイヤは crun」のように、ユースケースに応じて最適化する余地があります。
Kubernetes の文脈では CRI-O または containerd が中レイヤに入り、kubelet が CRI を通じて指示する形になります。
CLI: docker / podman / nerdctl / kubectl(kubelet)
Mid: dockerd / containerd / CRI-O
Low: runc / crun / youki