「Dockerは死んだ!」
2020年末、このニュースが広まると、コミュニティはパニックに陥りました。
しかし、実際に何が起こったのでしょうか?
>
🎯 この記事で扱うこと
- KubernetesがDockerを除外した理由(本当の理由)
- dockershimとは何か、なぜ問題になったのか
- containerd、CRI-Oなどの代替ランタイムとは何か
- Dockerイメージ(docker build)はまだ使えるのか
- 開発者・運用者が実際に何を変更する必要があるのか
📌 導入 / 背景
2020年12月、Kubernetes公式ブログに爆弾のような記事が一つ投稿されました。
“Kubernetes is deprecating Docker as a container runtime.”
この一文がTwitter、Reddit、Slackチャンネルを炎上させました。Kubernetesの共同創設者であるJoe Bedaでさえ、Twitterにこう書き込みました。
“Fascinating how this docker/docker-shim deprecation has created mass confusion.”
多くの人々が「もうDockerは使えないのか?」「私のdocker buildで作ったイメージはすべて使えなくなるのか?」とパニックに陥りました。
結論から申し上げますと:パニックになる必要はありません。しかし、正確に何が起こったのかを知る必要があります。
🔍 dockershimとは何か?
Kubernetes初期:Dockerしかなかった
Kubernetesが初めて登場したとき(2014年頃)、コンテナランタイムはDocker Engine一つだけでした。そのため、KubernetesはDockerサポートをコードにハードコーディングしましたが、このコンポーネントをdockershimと呼びます。
shimとは、元々機械の組み立て時に2つの部品間の隙間を埋める薄いクサビを指します。ソフトウェアでも同様に、異なるAPI間を接続するアダプターの役割を果たします。
CRIの登場:標準化の始まり
時間が経つにつれて、rkt、CRI-O、containerdのような様々なコンテナランタイムが登場しました。Kubernetesはこれらすべてをサポートするために、CRI(Container Runtime Interface)という標準APIを作成しました。
問題は、DockerがこのCRIをサポートしていなかったことです。DockerがCRIよりも先に登場したことを考えると、これは当然のことでした。
そのため、呼び出しパスはこのようになりました:
kubelet → dockershim → Docker Daemon → containerd → runc → 컨테이너
実際には、Dockerはイメージのダウンロードやコンテナの起動を直接行いません。内部のcontainerdがその役割を果たします。つまり、Kubernetesはコンテナを実行するために、kubelet → dockershim → Docker → containerdという長い中間プロセスを経る必要がありました。

🔍 なぜDockerを排除したのか?本当の理由3つ
1️⃣ メンテナンスの負担が大きすぎた
dockershimは最初から一時的な解決策でした(名前の通り:shim)。メンテナンスの負担が大きくなるにつれて、Kubernetesのメンテナーたちは「CRI標準を実装しないDockerのために、この負担を背負い続ける必要があるのか?」という疑問を抱き始めました。
2️⃣ 不要な中間段階
Kubernetes開発者がDockerを排除したかった大きな理由の一つは、中間段階が多すぎたことです。一つのコンテナを起動するのに、あまりにも多くのメッセージがアプリからアプリへと伝達されていました。
containerdに直接接続すると、パスはこのように単純化されます:
kubelet → containerd (CRI plugin 내장) → runc → 컨테이너
コンテナ一つを起動するのに0.1秒ずつ節約するだけでも、数百のコンテナを扱う環境では体感性能に差が出ます。
3️⃣ 新しい技術との非互換性
cgroups v2、ユーザーネームスペース(user namespaces)のような新しい機能は、dockershimと概ね互換性がありませんでした。dockershimのサポートを削除することで、これらの領域での追加開発が可能になります。
🗓️ タイムライン:このすべてはいつ起こったのか?
| 時期 | 出来事 |
| 2016年 | Kubernetes CRI仕様発表 |
| 2020年12月 | Kubernetes v1.20: dockershim 非推奨を公式宣言 |
| 2021年 | コミュニティの反発により削除スケジュールが一度延期 |
| 2022年4月 | Kubernetes v1.24: dockershim 完全削除 |
v1.20で非推奨が公式化されましたが、告知が適切に行われなかったため、コミュニティにパニックが発生しました。「Dockerという会社がなくなるのか?」「Dockerで作ったイメージが実行できなくなるのか?」といった誤解から混乱の大部分が生じました。
🔍 では、今は何を使うのか?
containerd — 事実上の標準
containerdは、元々Dockerが開発し、その後CNCF(Cloud Native Computing Foundation)に寄贈された汎用コンテナランタイムです。コンテナのライフサイクルを管理し、Kubernetesの内部および外部の両方で使用可能です。
AWS EKS、Azure AKS、Google GKEのような主要なマネージドKubernetesサービスは、すでにcontainerdをデフォルトのランタイムとして使用しています。もしAzureを使用しているなら、AKSノードはすでにcontainerdが稼働しています。
CRI-O — Kubernetes専用の軽量ランタイム
Red Hatが主導するプロジェクトで、Kubernetesでのみ使用するために作られた軽量ランタイムです。OpenShift環境で主に見られます。
cri-dockerd — Dockerを使い続けたい場合
MirantisとDockerは、dockershimがKubernetesから削除された後も、これを独立したオープンソースのCRIインターフェースとして維持管理することに合意しました。cri-dockerdをインストールすれば、依然としてDockerをランタイムとして使用できますが、追加のインストール負担が生じます。
💻 実際に何が変わったのか?(運用者視点)
コンテナ確認コマンドの変化
# ❌ 今、ノードでこれを実行しても何も表示されません
docker ps
# ✅ containerd環境ではこれを使うべきです
crictl ps
# ✅ または名前空間を指定して
ctr -n k8s.io containers list
ランタイム確認方法
# ノードで使用中のランタイムを確認
kubectl get node -o wide
# CONTAINER-RUNTIME列で確認可能
# 例: containerd://1.7.x
containerdのインストールと基本設定(Ubuntu基準)
# containerdをインストール
sudo apt-get update
sudo apt-get install -y containerd
# デフォルト設定ファイルを生成
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 restart containerd
sudo systemctl enable containerd
イメージビルドは依然としてDockerで行ってもよい ✅
# これは依然として完全に有効です
docker build -t myapp:v1.0 .
docker push myregistry.io/myapp:v1.0
# Kubernetesにデプロイする際のイメージ形式は同じ
kubectl apply -f deployment.yaml
⚠️ 注意事項 / よくある間違い
1. docker psでPodをデバッグしようとしない
containerdを使用するノードでdocker psを実行しても、Podコンテナは表示されません。containerdのような他のランタイムを使用する場合、docker psやdocker inspectコマンドでコンテナ情報を取得することはできません。kubectl exec、kubectl logs、crictl psを活用してください。
2. Dockerデーモンに依存するツールを確認する必要がある
Kubernetesインフラストラクチャの外部でDockerコマンドを実行するスクリプトやデーモン、例えば監視エージェントやセキュリティエージェントがインストールされている場合は、確認が必要です。
3. プライベートレジストリの設定場所が異なる
Dockerでdaemon.jsonで管理していたプライベートレジストリミラーの設定は、containerdでは/etc/containerd/config.tomlで行う必要があります。
# /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."myregistry.io"]
endpoint = ["https://myregistry.io"]
✅ まとめ / 締めくくり
Dockerは死んでいません。役割が分離されただけです。
| 役割 | ツール | ステータス |
| イメージビルド | docker build | ✅ 依然として有効 |
| イメージプッシュ | docker push | ✅ 依然として有効 |
| ローカル開発 | Docker Desktop | ✅ 依然として有効 |
| K8sコンテナランタイム | containerd / CRI-O | ✅ 現在の標準 |
| dockershim | 削除済み | ❌ v1.24以降なし |
Dockerは、開発作業中に人間が非常に簡単に操作できるようにする多くのUX改善機能を提供します。しかし、Kubernetesは人間ではないため、それらのUX改善機能は必要ありません。そのため、KubernetesはDockerのコアエンジンであるcontainerdと直接対話する道を選んだのです。
次のステップとして推奨される内容:
- 現在稼働中のKubernetesクラスターのランタイムを確認する: kubectl get node -o wide
- crictlコマンドを習得する(containerd環境のデバッグに必須)
- AKS/EKS/GKE使用時のランタイムデフォルト設定ドキュメントを確認する

コメントを残す