In this lesson, you will learn how the Container Runtime Interface (CRI) acts as the bridge that allows the Kubelet to communicate with and command various container runtimes.
Previously, we discussed how the Kubelet is responsible for ensuring that containers are running as expected on a node. However, the Kubelet itself doesn't know how to pull an image, extract a filesystem, or signal a Linux kernel to start a process. It needs a specialized tool to perform those low-level tasks. This is where the Container Runtime Interface (CRI) comes in.
The CRI as a Translator
Think of the CRI as a standardized language. Before CRI existed, Kubernetes had to be hard-coded to work with specific runtimes. By implementing CRI, Kubernetes defined a clear set of instructions—such as RunPodSandbox, CreateContainer, and StopContainer—that any runtime must understand to work with the Kubelet.
Because of this interface, the Kubelet remains "runtime-agnostic." It sends a standardized request to the CRI socket (typically located at /run/containerd/containerd.sock), and the runtime (like containerd or CRI-O) handles the heavy lifting.
A Practical Illustration
When you deploy a Pod, the Kubelet sends a message through the CRI interface to the runtime. You can see the result of this interaction when you inspect the status of a container on the host:
# Example: Inspecting a runtime-managed container
crictl ps
If you ever need to change your container runtime (for example, switching from Docker/Dockershim to containerd), you don't need to rebuild the Kubelet. You simply update the configuration file on the node to point to the new runtime's socket:
# /var/lib/kubelet/kubeadm-flags.env excerpt
--container-runtime-endpoint=unix:///run/containerd/containerd.sock
By decoupling the Kubelet from the specific runtime implementation, the CRI allows developers to swap out underlying technologies—such as using gVisor for higher security or containerd for standard performance—without changing the core Kubernetes logic or your application manifests.
Key Takeaway: The CRI provides a pluggable, standardized interface that allows the Kubelet to execute containers without needing to know the specific technical implementation details of the underlying runtime.