LabHub

ブログ

コンテナランタイム 2026 完全ガイド - containerd · runc · Podman · CRI-O · Kata · gVisor · Firecracker · Wasm 深掘り

한국어English日本語

はじめに — 2026年5月、コンテナランタイムは「多層隔離の時代」へ

Docker がコンテナと同義だった時代は終わった。2026年5月時点で Kubernetes クラスタの 95% 以上は containerd または CRI-O で動いている。開発機では PodmanDocker Desktop がシェアを分け合い、サーバーレスのバックエンドは Firecracker が事実上の標準だ。そして Wasm ランタイムがコンテナの一部領域を侵食し始めた。WasmEdge と wasmtime が runwasi という containerd-shim で Kubernetes に直結する。

本稿はマーケティング比較ではなく「2026年の本番で、どのランタイムがどこに入っているか」を正直に書く。OCI イメージ仕様、CRI、低レベルランタイム、隔離強度、イメージビルド、レジストリ、署名、脆弱性スキャンまでフルスタックで触れる。

コンテナスタックの 5 層 — OCI イメージからカーネルまで

まず全体像を見よう。2026年の標準コンテナスタックは次の 5 層に分解できる。

  1. OCI イメージフォーマット (image-spec): マニフェスト + 階層 tar + config JSON
  2. レジストリ (distribution-spec): ECR、GAR、Harbor、Quay は同じ API
  3. 高レベルランタイム (CRI/エンジン): containerd、CRI-O、Docker Engine、Podman
  4. 低レベルランタイム (OCI runtime): runc、crun、youki、kata-runtime、runsc(gVisor)
  5. 隔離メカニズム: namespaces + cgroups、マイクロ VM、ユーザー空間カーネル、Wasm サンドボックス

これらの層は OCI image-specOCI runtime-spec という 2 つの標準で繋がれている。どのビルダーで作ったイメージでも、どのランタイムでも動くことが約束されている。2026年時点でその約束はほぼ破られていない。

containerd — Kubernetes の既定 CRI

containerd は元々 Docker Engine から切り出されたデーモンで、2017年に CNCF を卒業し、その後 Kubernetes の事実上の標準 CRI 実装となった。EKS、GKE、AKS、OpenShift いずれも既定は containerd だ。Docker Desktop 内部でも containerd が動いている。

containerd の構造はシンプルだ。

containerd 2.0 (2025年末 GA) からは NRI (Node Resource Interface)、ユーザー空間 NRI プラグイン、Wasm shim (runwasi) 連携がファーストクラスになった。nerdctl は containerd の Docker 互換 CLI で、ほぼ同じコマンドが使える。

# nerdctl で containerd を直接操作
sudo nerdctl pull alpine:3.20
sudo nerdctl run --rm -it alpine:3.20 sh
sudo nerdctl images
sudo nerdctl ps -a

# CRI プラグインの状態確認
sudo crictl info | jq '.config.containerd'
sudo crictl ps

runc · crun · youki — OCI 低レベルランタイムの三つ巴

OCI runtime 仕様は「config.json と rootfs ディレクトリを受け取ってコンテナを起動せよ」というインタフェースだ。これを実装する低レベルランタイムが 3 つある。

3 つとも OCI 仕様に従うため、containerd の runtimes 設定で差し替え可能だ。

# /etc/containerd/config.toml の一部
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.crun]
  runtime_type = "io.containerd.runc.v2"
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.crun.options]
    BinaryName = "/usr/bin/crun"

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.youki]
  runtime_type = "io.containerd.runc.v2"
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.youki.options]
    BinaryName = "/usr/local/bin/youki"

CRI-O — Kubernetes 専用の軽量 CRI

CRI-O は Red Hat 主導の Kubernetes 専用 CRI だ。Docker 互換機能を持たず、kubelet と OCI ランタイムをつなぐ橋に徹する。OpenShift の既定 CRI であり、ノード上のメモリ使用量と表面積が containerd より小さいという利点がある。

containerd と CRI-O のどちらを選ぶかは運用チームの慣れ次第になることが多い。EKS・GKE の既定をそのまま使うなら containerd、OpenShift 上なら CRI-O だ。2026年時点で両者の隔離強度や機能差はほぼない。

Docker Engine — デスクトップとレガシーサーバーに残る席

Docker Engine は 2026年も生きているが役割は狭まった。デスクトップ (Docker Desktop) と一部のレガシーサーバーで既定エンジンを務めるくらいで、Kubernetes ノードからはほぼ消えた。Docker Engine 自体も内部的に containerd を使う薄いラッパーに近い。

Docker が依然強いのは 開発者 UX だ。docker compose でマルチコンテナ開発環境を立ち上げる流れは圧倒的に普及しており、Buildx と Docker Build Cloud がビルド速度を押し上げた。そのため「本番は containerd、開発は Docker Desktop」という組み合わせは未だ多い。

Podman + Buildah + Skopeo — ルートレス・デーモンレスの三点セット

Podman は Docker 互換 CLI を提供しつつデーモンを持たない。コンテナそれぞれがユーザープロセスとして起動し、systemd がライフサイクルを管理する。デーモンがないため root 権限も不要 (ルートレス)。Fedora・RHEL・CentOS Stream の既定であり、Ubuntu LTS にも標準パッケージとして入った。

3 つとも Red Hat 主導だが OCI 標準のみに従うので、他のランタイムやレジストリと自由に混ぜられる。

# Podman ルートレス
podman run --rm -it --userns=keep-id alpine:3.20 id

# Buildah によるデーモンレスビルド
buildah bud -t myapp:1.0 .
buildah push myapp:1.0 docker://registry.example.com/myapp:1.0

# Skopeo によるレジストリ間コピー
skopeo copy --src-creds user:pass --dest-creds user:pass \
  docker://docker.io/library/nginx:1.27 \
  docker://harbor.example.com/library/nginx:1.27

Kata Containers 3.x — 軽量 VM による強い隔離

Kata Containers はコンテナインタフェースの裏に軽量 VM を立ち上げてカーネルを分離する。ホストカーネルの CVE がコンテナ脱出に直結しないように防ぐ。3.x 系 (2024-2026) は QEMU、Firecracker、Cloud Hypervisor をハイパーバイザーとして選べ、起動時間が 1-2 秒台まで落ちた。

Kata は containerd の runtimeskata-qemukata-fckata-clh として登録する。Kubernetes では RuntimeClass でワークロードごとに隔離レベルを分けられる。

apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: kata-clh
handler: kata-clh
---
apiVersion: v1
kind: Pod
metadata:
  name: untrusted-workload
spec:
  runtimeClassName: kata-clh
  containers:
    - name: app
      image: registry.example.com/untrusted-app:1.0

gVisor — Google のユーザー空間カーネルサンドボックス

gVisor (runsc) は Google が作ったユーザー空間カーネル実装だ。ホストカーネル syscall をそのまま通さず、runsc 内部の自前カーネルで代行する。VM ではないので軽量だが、ホストカーネル表面積を極端に減らせる。

弱点は一部のワークロードでネットワークやファイル I/O が遅くなる点だ。そのため 信頼できないコード実行 (サーバーレス関数、CI ビルドランナー、AI 推論のユーザーコード) によく合い、DB のような I/O ヘビーなワークロードには合わない。Google Cloud Run や GKE Sandbox は内部で gVisor を使う。

# Docker に runsc を登録して実行
sudo runsc install
sudo systemctl restart docker
docker run --rm --runtime=runsc alpine:3.20 uname -a
# 出力のカーネルバージョンはホストではなく runsc が模倣する値になる

Firecracker — AWS のマイクロ VM

Firecracker は AWS が作った KVM ベースのマイクロ VM モニタだ。Lambda、Fargate、App Runner の隔離単位は Firecracker microVM である。VM 1 台が 5MB 未満のメモリオーバーヘッドで 125ms 以内に起動する。Rust で書かれ、デバイスモデルを可能な限り削ってセキュリティ表面を縮小している。

Firecracker は REST API で vCPU、メモリ、カーネルイメージ、rootfs、ネットワークインタフェースを設定してからインスタンスを起動する。

{
  "boot-source": {
    "kernel_image_path": "/var/lib/firecracker/vmlinux",
    "boot_args": "console=ttyS0 reboot=k panic=1 pci=off"
  },
  "drives": [
    {
      "drive_id": "rootfs",
      "path_on_host": "/var/lib/firecracker/rootfs.ext4",
      "is_root_device": true,
      "is_read_only": false
    }
  ],
  "machine-config": {
    "vcpu_count": 2,
    "mem_size_mib": 512,
    "smt": false
  }
}

Cloud Hypervisor — Intel・AWS・Microsoft 共同のマイクロ VM

Cloud Hypervisor は Intel が始め、AWS、Microsoft、Tencent などが加わった共同プロジェクトだ。Firecracker と同じく KVM ベースの VMM だが、より豊富なデバイスモデルと ARM・x86 両対応を持つ。Kata Containers の kata-clh バックエンド、Azure Confidential Containers、AWS の一部コンテナ隔離で採用されている。2026年のマイクロ VM 業界は Firecracker と Cloud Hypervisor が二分していると言ってよい。

Wasm ランタイム — Kubernetes に入ってきた新しい隔離単位

WebAssembly はコンテナの一部領域を急速に侵食している。WasmEdge、wasmtime、wasmer、lunatic などのランタイムは起動時間がマイクロ秒単位、メモリオーバーヘッドはコンテナより一桁小さい。CNCF は runwasi という containerd-shim を通じて Wasm を Kubernetes pod として直接実行する道を標準化した。

Kubernetes で Wasm ワークロードを動かす一般的な流れは、runwasi を containerd に登録して RuntimeClass で振り分けることだ。

apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: wasmedge
handler: wasmedge
---
apiVersion: v1
kind: Pod
metadata:
  name: hello-wasm
spec:
  runtimeClassName: wasmedge
  containers:
    - name: hello
      image: registry.example.com/hello-wasm:1.0
      command: ['/hello.wasm']

WASI · Wasm Component Model — 互換性の標準

Wasm をコンテナの代替たらしめる核は WASI (WebAssembly System Interface) だ。preview 1 から始まり、2024年に preview 2 が安定、2025年末には component model が GA に近づいた。component model は言語間の ABI を統一し、Rust 製の Wasm モジュールが Go・JS・Python ホストでそのまま動く。

2026年時点で WASI / component model が最も活発に使われているのは エッジコンピューティング (Cloudflare Workers、Fastly Compute)、プラグインシステム (Envoy、Open Policy Agent、Istio)、AI 推論 (WasmEdge + ONNX、GGUF) だ。

隔離強度の比較 — 何をいつ使うか

ランタイム選定の主軸は隔離強度と起動時間だ。2026年5月時点の代表的な組み合わせを整理する。

表面的な隔離強度ではマイクロ VM と Kata が最も強く、Wasm はそれより弱いがコンテナ脱出系の脅威モデル自体が異なる。runc が最も弱いが最速で最も互換性が高い。

OCI イメージビルダー — BuildKit · kaniko · buildah · jib · ko · Buildpacks

イメージを作る道具は 2026年でも豊富だ。どれを選ぶかは環境 (ビルダーに Docker デーモンがあるか、Kubernetes の中で作るか) と言語スタックに依る。

BuildKit のキャッシュマウントを使った典型的なマルチステージ Dockerfile は次のとおり。

# syntax=docker/dockerfile:1.7
FROM golang:1.23 AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
    go mod download
COPY . .
RUN --mount=type=cache,target=/root/.cache/go-build \
    --mount=type=cache,target=/go/pkg/mod \
    CGO_ENABLED=0 go build -o /out/app ./cmd/server

FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=builder /out/app /app
USER nonroot:nonroot
ENTRYPOINT ["/app"]

OCI イメージフォーマット · マニフェスト v2 · インデックス

OCI イメージ仕様は 3 つのオブジェクトから成る。マニフェスト (レイヤと config を参照)、config JSON (entrypoint、環境変数、history)、レイヤ (tar.gz または zstd 圧縮)。マルチアーキは イメージインデックス (マニフェストリスト) でまとめる。

2026年に入って標準化が進んだ変更には OCI image-spec 1.1 の zstd レイヤ、OCI artifacts (イメージ以外のデータも同フォーマットで push)、referrer API (OCI 1.1 dist-spec) がある。これにより cosign 署名、SBOM、attestation が同じレジストリに付随物として乗る。

OCI Distribution · レジストリフルスタック

レジストリも OCI distribution 仕様に統一された。どのクラウドレジストリでも同じ API が動く。

イメージ署名 — cosign · notation (Notary v2)

イメージ出所保証は 2024年から標準化が進んだ。

Kubernetes では admission controller (Sigstore Policy Controller、Kyverno、OPA Gatekeeper) で未署名イメージのデプロイを止める。

# cosign 鍵なし署名と検証
cosign sign --yes registry.example.com/myapp:1.0
cosign verify \
  --certificate-identity-regexp 'https://github.com/myorg/.*' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  registry.example.com/myapp:1.0

脆弱性スキャン — Trivy · Grype · Snyk · Clair

ビルドや push の段階でイメージ脆弱性をスキャンする道具も標準化された。

2026年時点で最もよく見る組み合わせは、GitHub Actions/GitLab CI で Trivy が ビルドを止め、Harbor や ECR が push 後に自動スキャン、Kubernetes admission が cosign 署名 + Trivy レポートをまとめて検証する流れだ。

rootless · userns · cgroups v2 — 2026年の基本線

Linux ホスト水準の隔離基本線も整った。

Kubernetes RuntimeClass とマルチランタイムノード

Kubernetes RuntimeClass はノードに登録された複数ランタイムからワークロードごとに使うものを選ぶ標準 API だ。1 クラスタ内で信頼ワークロードは runc、ユーザーコード実行は gVisor、マルチテナントは Kata、エッジ関数は Wasm に分けるのがよくある絵になる。

ランタイムごとにノードプールを分けるのが運用的に単純だが、同じノードに複数ランタイムを登録して admission で振り分けるパターンも増えた。マネージド Kubernetes では GKE Sandbox (gVisor)、AKS Confidential Containers (Kata + Cloud Hypervisor)、EKS on Fargate (Firecracker) がそれぞれ独自の道を行く。

ビルドキャッシュと決定論的ビルド

2026年のビルドキャッシュは事実上必須だ。BuildKit と buildah はレジストリにキャッシュマニフェストを push する inline・registry キャッシュをサポートする。Bazel rules_oci、ko、jib は決定論的ビルド (同じ入力 → 同じダイジェスト) を保証する。決定論的ビルドは reproducible build 運動と SLSA 保証の土台だ。

CI で最も効くのは BuildKit のキャッシュマウントと外部キャッシュ (Buildx の --cache-to type=registry) を組み合わせて使うことだ。

韓国の事例 — Naver Container Engine と Coupang のランタイム遍歴

韓国は自前ランタイムを作るのではなく標準を深く使う方向で成熟した。

日本の事例 — Mercari の containerd 移行と LY Verda コンテナ

日本も OSS 標準を素早く採用した側だ。

移行パターン — Docker Engine から containerd へ

レガシー環境で最もよくある移行は Docker Engine → containerd だ。Kubernetes 1.24 で dockershim が削除されて以降、EKS・GKE・AKS・OpenShift はすべて自動的に切り替わったが、自前運用の Kubernetes には依然移行が残っている。

移行の要点は (1) ノードのコンテナランタイム差し替え、(2) モニタリングとロギングエージェントのソケットパス変更 (/var/run/docker.sock → /run/containerd/containerd.sock)、(3) 社内ビルドパイプラインが Docker デーモンに依存しないよう BuildKit・kaniko・buildah に分離することだ。

コスト · 運用視点 — どの組み合わせを選ぶか

2026年5月時点で推奨される組み合わせはワークロードの性質によって次のようになる。

セキュリティのベストプラクティス — 2026年版チェックリスト

ランタイム単位ではなくフルスタックで押さえるべき項目だ。

まとめ — コンテナの次の 10 年

コンテナは終わっていない。だが「Docker コンテナ」という単一モデルは終わった。2026年5月時点でコンテナインタフェースの裏には namespaces+cgroups からマイクロ VM、ユーザー空間カーネル、Wasm サンドボックスまで 5 種類以上の隔離メカニズムが入っている。OCI 標準がその多層を繋いでいる。

これからの 10 年の変化は 2 方向だ。1 つは Wasm がコンテナの一部領域を侵食し続けること。エッジ、プラグイン、AI 推論から始まり、一般バックエンドにも広がる可能性がある。2 つ目は コンフィデンシャルコンピューティング (AMD SEV-SNP、Intel TDX、ARM CCA) ベースの隔離がマルチテナントと規制ワークロードの標準になること。どちらの流れも OCI と Kubernetes 標準の上で起きる。標準を深く理解しているチームほど素早く適応できる。

References

コメント

まだコメントはありません。

ログインするとコメントできます