コンテナが起動しない、ディスクが付かない、外部アドレスが決まらない。 調べるときは、それぞれの仕事を担当するプログラムから見ていくと、確認先を絞れます。
この章では、ここまでの担当分けをクイズで確かめます。 後半の早見表では、症状から最初に見るリソースやログを探せます。
GOAL この章のゴール
- コンテナの起動やディスクの接続など、仕事ごとの担当を選べる
- Docker と Kubernetes の担当分けの違いを説明できる
- 症状に応じて、最初に見るリソースやログを選べる
クイズ: 機能からインターフェースへ
10 問あります。 選ぶとすぐ答えと理由が出ます。
Q1この機能を担うインターフェースは? Pod に IP アドレスが割り当てられる
選んでください
Docker が全部と被っていた
Part 3 と Part 4 を通じて、dockershim の削除がなぜ「ランタイムの差し替え」以上の意味を持ったかが見えてきます。
Docker Engine は、コンテナの実行のほかに、ネットワーク (既定の bridge ネットワーク docker0 と、host / overlay / macvlan などのドライバー)、ボリューム (docker volume と volume driver のプラグイン)、クラスタ管理 (Swarm mode) を 1 つのデーモンに持っています。
Kubernetes は同じ 4 つの仕事を、ランタイムは CRI、ネットワークは CNI、ボリュームは CSI、クラスタ管理は本体の scheduler と controller (クラウドとの接点は CPI) で、それぞれ別に持ちます。
両者を同じノードで動かすと、Kubernetes が使うのはコンテナの実行だけで、docker network も docker volume も Swarm も、ただ存在するだけになります。
dockershim は、kubelet の CRI の呼び出しを Docker Engine の API に変換して、その 1 つの仕事だけを使うためのプログラムでした。
1.24 でそれを外したあとは、kubelet が containerd と直接話すので、変換のための 1 段が要りません。
全体図をもう一度
| インターフェース | 呼ぶ側 | 呼ばれる側 | 運び方 | 2026 年の状態 |
|---|---|---|---|---|
| CRI | kubelet | containerd / CRI-O | gRPC over UNIX socket | v1 のみ (1.26 から)。dockershim は 1.24 で削除 |
| CNI | ランタイム | /opt/cni/bin のバイナリ |
exec + 環境変数 + stdin JSON | spec 1.1.0。Cilium / Calico / VPC CNI |
| CSI | kubelet と sidecar | CSI driver | gRPC over UNIX socket | in-tree プラグイン削除済み (1.31 まで) |
| CPI | CCM | クラウド API | Go interface + REST | in-tree プロバイダー削除済み (1.31) |
| Device Plugin | kubelet | ベンダー plugin | gRPC over UNIX socket | 1.26 GA、CDI 対応は 1.31 GA |
| DRA | scheduler と kubelet | DRA driver | API オブジェクト + gRPC | 1.34 GA、resource.k8s.io/v1 |
| Gateway API | Gateway controller | データプレーン | API オブジェクト (CRD) | v1.6 系。ingress-nginx は 2026 年 3 月に退役 |
| CRD / 集約 API | 自作 controller | apiserver | REST / watch | 拡張の標準手段 |
症状から疑う場所へ
障害のときに最初に見る場所を、症状ごとに並べます。
| 症状 | 疑う場所 | 最初に見るもの |
|---|---|---|
Pod が ContainerCreating で FailedCreatePodSandBox |
CRI → CNI | kubectl describe pod のメッセージ。crictl info の NetworkReady、CNI プラグインのログ |
Pod が ErrImagePull |
CRI (ImageService) | レジストリの認証、crictl pull で再現 |
Node が NotReady で network plugin is not ready |
CNI | /etc/cni/net.d の有無、CNI の DaemonSet (cilium など) の状態 |
PVC が Pending |
CSI (provision) | kubectl describe pvc のイベント、external-provisioner のログ、StorageClass の volumeBindingMode |
Pod が FailedAttachVolume / FailedMount |
CSI (attach / mount) | VolumeAttachment、external-attacher と Node plugin のログ |
新しい Node に Pod が乗らない、uninitialized taint |
CPI (Node controller) | CCM の Pod とログ、kubelet の --cloud-provider |
EXTERNAL-IP が <pending> |
CPI (Service controller) | CCM が居るか、Service のイベントにロードバランサー同期の失敗が出ているか |
GPU の Pod が Unschedulable |
Device Plugin / DRA | Node の capacity、ResourceSlice、plugin の DaemonSet |
Gateway が Programmed: False |
Gateway API | GatewayClass の controller が動いているか、Gateway の status |
実機: 4 つのインターフェースの実装を確かめる
この Part で使ったコマンドを 1 セットにまとめました。 順に流すと、自分のクラスタでそれぞれの仕事を担当しているプログラムが分かります。
echo "== CRI"; kubectl get node -o jsonpath='{.items[0].status.nodeInfo.containerRuntimeVersion}{"\n"}'
echo "== CNI"; kubectl -n kube-system get ds cilium -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
echo "== CSI"; kubectl get csidrivers -o name
echo "== CPI"; kubectl get node -o jsonpath='{.items[0].spec.providerID}{"\n"}'
echo "== DRA"; kubectl api-resources --api-group=resource.k8s.io -o name
echo "== Gateway"; kubectl get gatewayclasses -o name出力例
== CRI
containerd://2.4.x
== CNI
quay.io/cilium/cilium:v1.20.2
== CSI
csidriver.storage.k8s.io/csi.kubevirt.io
== CPI
kubevirt://<vm 名>
== DRA
deviceclasses.resource.k8s.io
resourceclaims.resource.k8s.io
...
== Gateway
gatewayclass.gateway.networking.k8s.io/ciliumcontainerd、Cilium、kubevirt-csi、kubevirt CCM、Cilium の Gateway。 それぞれ別のプロジェクトが、同じインターフェースの規約に合わせて作ったものです。 EKS なら containerd、VPC CNI、EBS CSI、cloud-provider-aws、AWS Load Balancer Controller に置き換わりますが、kubelet や controller が頼む相手の種類と、頼み方は変わりません。 Part 5 では、その「クラウド側の実装」を見ていきます。
ふりかえり
Qdockershim の削除で実際に変わったことは?
Kubernetes が Docker から使っていたのはランタイムの層だけで、ネットワークとボリュームは最初から CNI と CSI でした。イメージは OCI 形式なので影響を受けません。
QPVC が Pending、Pod のイベントに FailedAttachVolume。この 2 つで疑う段は?
PVC の Bound までが provision (external-provisioner)、VolumeAttachment が true になるまでが attach (external-attacher)、その後が mount (kubelet と Node plugin) です。
QEKS でこの Part の 4 つのインターフェースの実装を並べると?
EKS のノードは containerd、ネットワークは amazon-vpc-cni-k8s、ボリュームは aws-ebs-csi-driver、クラウド連携は cloud-provider-aws (CCM) です。2 つ目は in-tree 時代の構成で、今は全て置き換わっています。
参考
- Cluster Architecture, Kubernetes Documentation: https://kubernetes.io/docs/concepts/architecture/
- Container Runtime Interface (CRI), Kubernetes Documentation: https://kubernetes.io/docs/concepts/architecture/cri/
- Dockershim Removal FAQ, Kubernetes Blog: https://kubernetes.io/blog/2022/02/17/dockershim-faq/
- Network Plugins, Kubernetes Documentation: https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/
- Persistent Volumes, Kubernetes Documentation: https://kubernetes.io/docs/concepts/storage/persistent-volumes/
- Cloud Controller Manager, Kubernetes Documentation: https://kubernetes.io/docs/concepts/architecture/cloud-controller/
- Device Plugins, Kubernetes Documentation: https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/
- Dynamic Resource Allocation, Kubernetes Documentation: https://kubernetes.io/docs/concepts/resource-management/dynamic-resource-allocation/
- Ingress NGINX Retirement, Kubernetes Blog: https://kubernetes.io/blog/2025/11/11/ingress-nginx-retirement/
- Gateway API のリリース一覧: https://github.com/kubernetes-sigs/gateway-api/releases
- Networking overview, Docker Docs: https://docs.docker.com/engine/network/
- Volumes, Docker Docs: https://docs.docker.com/engine/storage/volumes/
- Swarm mode overview, Docker Docs: https://docs.docker.com/engine/swarm/
読み切ると称号を獲得
境界線を引く者
この Part を読み切りました。
称号一覧