AI

コンテナランタイム比較:containerd vs CRI-O vs Docker Engine でKubernetesを動かす

オープンソースラボ編集部2026年6月14日

コンテナランタイム比較:containerd vs CRI-O vs Docker Engine でKubernetesを動かす

Kubernetes 1.24以降でDockerShimが削除され、CRI(Container Runtime Interface)準拠のコンテナランタイムを直接選ぶ必要があります。containerd(CNCF卒業プロジェクト・最も普及)・CRI-O(RedHat製・Kubernetes専用)・Docker Engine(Dockerfileは使えるが本番Kubernetesでは非推奨)の違いを理解して正しいランタイムを選びましょう。

コンテナランタイムを選ぶ理由

  • Kubernetes 1.24以降: dockershimが削除されてDocker EngineはCRIなしでは使用不可
  • パフォーマンス: containerdとCRI-Oは中間レイヤーが少ない分軽量・高速
  • セキュリティ: runC(OCI)・gVisor・Kata Containersなど代替ランタイムに切り替え可能
  • 管理コスト: kubeadm/RKE2/k3sのデフォルトがcontainerdに変更済み(設定不要で使える)

主要ランタイムの概要

containerd

2016年公開、Go製のOSSです。GitHubスター18k+。CNCFの卒業プロジェクトで最も広く使われているCRI準拠ランタイムです。Docker Engineの中でも使われており、AWS EKS・GKE・AKSのデフォルトランタイムです。crictlctrnerdctl(Dockerコンパチ)でコンテナを操作できます。

# containerd インストール(Ubuntu/Debian)
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg

# Docker公式リポジトリからcontainerdをインストール
curl -fsSL https://download.docker.com/linux/ubuntu/gpg |   sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg]   https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" |   sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y containerd.io

# デフォルト設定を生成してsystemdに対応
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# systemd cgroupドライバーに変更(Kubernetes必須設定)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/'   /etc/containerd/config.toml

sudo systemctl enable --now containerd
sudo systemctl status containerd
# /etc/containerd/config.toml - 主要設定項目
version = 2

[plugins."io.containerd.grpc.v1.cri"]
  sandbox_image = "registry.k8s.io/pause:3.9"

  [plugins."io.containerd.grpc.v1.cri".containerd]
    default_runtime_name = "runc"

    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
      runtime_type = "io.containerd.runc.v2"

      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
        SystemdCgroup = true  # Kubernetes必須

    # gVisorランタイム追加(セキュリティ強化)
    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc]
      runtime_type = "io.containerd.runsc.v1"

  [plugins."io.containerd.grpc.v1.cri".registry]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
        endpoint = ["https://registry-1.docker.io"]
      # プライベートレジストリ設定
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.yourcompany.com"]
        endpoint = ["https://registry.yourcompany.com"]

    [plugins."io.containerd.grpc.v1.cri".registry.configs]
      [plugins."io.containerd.grpc.v1.cri".registry.configs."registry.yourcompany.com".auth]
        username = "robot_user"
        password = "token_value"
# nerdctl: Docker CLI互換のcontainerdクライアント
# Docker移行時にdockerコマンドをnerdctlに置き換えるだけで使える

# nerdctlインストール
NERDCTL_VERSION=2.0.2
curl -Lo /tmp/nerdctl.tar.gz   "https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz"
sudo tar Cxzf /usr/local/bin /tmp/nerdctl.tar.gz nerdctl

# Docker互換コマンド
nerdctl pull nginx:alpine
nerdctl run -d -p 8080:80 --name web nginx:alpine
nerdctl ps
nerdctl exec -it web sh
nerdctl build -t myapp:v1 .
nerdctl push registry.yourcompany.com/myapp:v1

# crictl でKubernetes環境のコンテナを操作
sudo crictl --runtime-endpoint unix:///run/containerd/containerd.sock ps
sudo crictl images
sudo crictl pods

CRI-O

2016年公開、Go製のOSSです。GitHubスター2.5k+。Kubernetes専用に設計されたCRI準拠ランタイムで、Kubernetesが使う機能のみを実装した最小構成です。OpenShift(RedHat)のデフォルトランタイムです。

# CRI-O インストール(Kubernetes 1.30向け)
export KUBERNETES_VERSION=v1.30
export PROJECT_PATH=prerelease:/main

# OBS(Open Build Service)からインストール
curl -fsSL https://pkgs.k8s.io/addons:/cri-o:/${PROJECT_PATH}/deb/Release.key |   sudo gpg --dearmor -o /etc/apt/keyrings/cri-o-apt-keyring.gpg

echo "deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg]   https://pkgs.k8s.io/addons:/cri-o:/${PROJECT_PATH}/deb/ /" |   sudo tee /etc/apt/sources.list.d/cri-o.list

sudo apt-get update
sudo apt-get install -y cri-o

sudo systemctl enable --now crio
sudo systemctl status crio

# kubeadmでCRI-Oを使うクラスター初期化
sudo kubeadm init   --pod-network-cidr=10.244.0.0/16   --cri-socket=unix:///var/run/crio/crio.sock
# /etc/crio/crio.conf.d/10-runtime.conf
[crio.runtime]
# デフォルトランタイム
default_runtime = "runc"

[crio.runtime.runtimes.runc]
runtime_path = "/usr/bin/runc"
runtime_type = "oci"

# Kata Containers(VM分離ランタイム)
[crio.runtime.runtimes.kata-containers]
runtime_path = "/usr/bin/kata-runtime"
runtime_type = "vm"

[crio.image]
# 使用するレジストリを制限(セキュリティ強化)
registries = ["registry.access.redhat.com", "docker.io", "registry.yourcompany.com"]

Docker Engine(参考)

Docker Engineは現在もローカル開発・CI環境で最も使われています。Kubernetes本番環境ではcri-dockerd(Mirantis製シム)を経由して使えますが、containerd/CRI-Oが推奨です。

# Docker Engine インストール(ローカル開発用)
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER  # sudoなしでdockerを実行

# kubeadmでDocker Engineを使う場合(非推奨・レガシー)
# cri-dockerdが必要
sudo apt-get install -y cri-dockerd
sudo kubeadm init   --cri-socket unix:///var/run/cri-dockerd.sock

機能比較表

比較項目containerdCRI-ODocker Engine
CRI準拠cri-dockerd必要
Kubernetes推奨度△(レガシー)
OpenShift対応✅(デフォルト)
nerdctl/crictlcrictldocker CLI
メモリフットプリント最小

コンテナランタイムはDevOpsカテゴリ/categories/devopsのKubernetes・Helm・ArgoCD構成と密接に連携します。セキュリティカテゴリ/categories/securityのgVisor・Kata ContainersをcontainerdのRuntimeClassとして設定してサンドボックス分離を実現できます。

FAQ

Q. DockerからcontainerdにKubernetes環境を移行するには?

A. ノードのランタイムをcontainerdに変更する手順は: ①対象ノードをcordon/drainしてPodを退避②dockershim設定を削除③containerdをインストールして設定(SystemdCgroup=true)④kubeletの--container-runtime-endpointunix:///run/containerd/containerd.sockに変更⑤ノードをuncordonして復帰。既存のDockerイメージはそのままcontainerdで使用できます(OCIイメージ形式の互換性)。kubeadm環境ではkubeadm upgrade後に設定を変更するのが最も安全です。

Q. containerdとCRI-Oのどちらを選ぶべきですか?

A. マネージドKubernetes(EKS/GKE/AKS)や汎用用途ならcontainerdOpenShiftやRHEL系でKubernetes専用ならCRI-Oが向いています。実際の違いは小さく、設定はほぼ同じでcrictlコマンドは両方で使えます。k3s・RKE2・k0sはデフォルトでcontainerdを使用しています。新規クラスター構築ではよりエコシステムが大きいcontainerdを選ぶことが多いです。

Q. gVisorをcontainerdで使うにはどうしますか?

A. ①gVisorをインストール(apt-get install runsc)②containerd設定にrunscランタイムを追加③KubernetesのRuntimeClassリソースでhandler: runscを定義④PodSpecのruntimeClassName: gvisorでサンドボックスPodを作成。gVisorの制約: ①/procへのアクセスが制限される(一部のLinuxシステムコールをエミュレート)②パフォーマンスはrunCより10〜20%低下③インターネット向けのAPIサーバー・マルチテナント環境・機密データ処理Podに最適。

Q. コンテナランタイムのセキュリティベストプラクティスは?

A. ①rootlessコンテナ: containerd+rootlesskit(rootユーザーなしでコンテナを実行)②読み取り専用rootfs: PodSecurityContextでreadOnlyRootFilesystem: trueSeccompProfile: RuntimeDefaultプロファイルを適用してシステムコールを制限④AppArmor/SELinux: ノードのMACポリシーをコンテナに適用⑤イメージ署名検証: Cosign + Policy Controller(Sigstore)でサプライチェーン攻撃を防止⑥distrolessイメージ: Google Container Toolsのdistrolessベースイメージでシェル・パッケージマネージャーを含まない最小イメージを使用。

まとめ

ユースケース推奨ランタイム
マネージドK8s・汎用Kubernetescontainerd
OpenShift・RHEL・Kubernetes専用CRI-O
ローカル開発・CI環境Docker Engine

関連外部リソース

他の記事も読む

Let's Build Together

OSS導入、自社だけで悩まない。

ツール選定から構築・運用・AI活用まで、オープンソースラボ運営元のClasslessが伴走します。初回のご相談は無料です。