Container Runtime Interface — How Kubernetes Runs Containers
What Is the Container Runtime Interface in Simple Terms?
Kubernetes does not run containers directly — it delegates that work to a container runtime via a standard API called the Container Runtime Interface (CRI). Any runtime that implements CRI can work with Kubernetes — containerd, CRI-O, and others.
This is why Kubernetes deprecated Docker in version 1.24. Docker was not CRI-compliant. Kubernetes used a special adapter called the Docker shim to bridge Docker and CRI. When Kubernetes removed the shim, it switched to containerd directly — which is faster, simpler, and was always the actual engine doing the work anyway.
Before Kubernetes 1.24: kubelet -> Docker shim -> Docker daemon -> containerd -> runc ^ | extra layer, maintained by Kubernetes team After Kubernetes 1.24: kubelet -> CRI -> containerd -> runc ^ | clean interface, much simplerWhat This Means for You
If you are a developer: Almost nothing changes. Images built with Docker still work perfectly. Docker images ARE OCI images — containerd runs them. docker build, docker push still work. Only the runtime on Kubernetes nodes changed. If you are running Kubernetes: Kubernetes 1.24+: use containerd, not Docker Check runtime on your nodes: kubectl get nodes -o wide # Container Runtime: containerd://1.7.8 # <- containerd is the runtime, not dockerCRI Implementations
containerd (most common): Created by Docker, donated to CNCF Default runtime for most Kubernetes distributions Powers: EKS, GKE, AKS, kubeadm clusters Docker images work natively CRI-O: Designed specifically for Kubernetes Minimal footprint Used by: OpenShift, some kubeadm clusters Docker images work natively gVisor (sandboxed runtime): Google's container runtime with its own kernel VM-level isolation with container speed Used for: untrusted workloads, multi-tenant Kata Containers: Lightweight VMs that look like containers True VM isolation via hardware virtualization Used for: strict compliance requirementsChecking Your Runtime
# On a Kubernetes nodekubectl get nodes -o wide# CONTAINER-RUNTIME# containerd://1.7.8 # Check containerd directly on the nodesudo ctr versionctr containers list # crictl — CRI-compatible kubectl for node debuggingcrictl pscrictl imagescrictl logs container-idREMEMBER THIS**Remember:** The Docker deprecation in Kubernetes does not affect your workflow as a developer. You still build images with Docker, push to registries, and pull them in Kubernetes. The change was only on the Kubernetes node side — containerd runs your Docker images directly without needing Docker installed on the node.