Why Kubernetes Dropped Docker’s Dockershim: A Deep Dive into CRI and Runtime Flexibility
This article explains the rationale behind Kubernetes' decision to remove Dockershim, outlines the role of the Container Runtime Interface (CRI), compares Docker's feature set with CRI requirements, and discusses the impact on extensibility and future container runtimes.
Overview
Kubernetes is the de‑facto platform for container orchestration. Historically it used Docker as the default container runtime, communicating through a compatibility layer called Dockershim . In December 2020 the Kubernetes community announced the removal of Dockershim code from the repository, a change driven by the adoption of the Container Runtime Interface (CRI).
Dockershim
Dockershim is a shim process that sits between the Kubelet node agent and the Docker daemon. When the Kubelet needs to start, stop, or inspect containers, it sends gRPC requests to Dockershim, which forwards them to Docker. This layer existed solely to make Docker compatible with the Kubelet before CRI was available.
Container Runtime Interface (CRI)
CRI abstracts container runtime operations behind two gRPC services: RuntimeService and ImageService . Any runtime that implements these services can be used by Kubelet, eliminating the need for Docker‑specific code.
service RuntimeService {
rpc Version(VersionRequest) returns (VersionResponse) {}
rpc RunPodSandbox(RunPodSandboxRequest) returns (RunPodSandboxResponse) {}
rpc StopPodSandbox(StopPodSandboxRequest) returns (StopPodSandboxResponse) {}
rpc RemovePodSandbox(RemovePodSandboxRequest) returns (RemovePodSandboxResponse) {}
rpc PodSandboxStatus(PodSandboxStatusRequest) returns (PodSandboxStatusResponse) {}
rpc ListPodSandbox(ListPodSandboxRequest) returns (ListPodSandboxResponse) {}
rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}
rpc StartContainer(StartContainerRequest) returns (StartContainerResponse) {}
rpc StopContainer(StopContainerRequest) returns (StopContainerResponse) {}
rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse) {}
rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {}
rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {}
rpc UpdateContainerResources(UpdateContainerResourcesRequest) returns (UpdateContainerResourcesResponse) {}
rpc ReopenContainerLog(ReopenContainerLogRequest) returns (ReopenContainerLogResponse) {}
...
}
service ImageService {
rpc ListImages(ListImagesRequest) returns (ListImagesResponse) {}
rpc ImageStatus(ImageStatusRequest) returns (ImageStatusResponse) {}
rpc PullImage(PullImageRequest) returns (PullImageResponse) {}
rpc RemoveImage(RemoveImageRequest) returns (RemoveImageResponse) {}
rpc ImageFsInfo(ImageFsInfoRequest) returns (ImageFsInfoResponse) {}
}Design Rationale
Although Kubernetes primarily uses declarative APIs, CRI was deliberately designed as an imperative interface. A declarative runtime API would have required every runtime to re‑implement complex Pod‑level logic and keep up with rapid PodSpec evolution (e.g., init containers). Keeping the interface imperative lets Kubelet retain full control over the desired‑state reconciliation loop.
Why Docker Does Not Fit CRI
Docker is a full‑featured developer tool that includes image building, distribution, and a rich CLI. Kubernetes only needs the subset of functionality defined by CRI (container lifecycle and image management). Docker has no plans to implement CRI, and newer kernel features such as cgroups v2 and user namespaces cannot be exposed through Dockershim. Maintaining a compatibility shim for Docker therefore adds significant maintenance burden without providing value to the orchestration layer.
Impact of Removing Dockershim
Removing Dockershim allows Kubernetes to rely exclusively on CRI‑compatible runtimes such as containerd and CRI‑O . This reduces the code base, eliminates a source of bugs, and encourages the ecosystem to adopt lighter, purpose‑built runtimes. Projects that still need Docker can run Docker as a separate tool for local development, but it is no longer a supported runtime for production clusters.
References
Dockershim Deprecation FAQ: https://kubernetes.io/blog/2020/12/02/dockershim-faq/
Don’t Panic: Kubernetes and Docker: https://kubernetes.io/blog/2020/12/02/dont-panic-kubernetes-and-docker/
Removing dockershim from kubelet #1985: https://github.com/kubernetes/enhancements/pull/1985
CRI API definition (proto file): https://github.com/kubernetes/cri-api/blob/master/pkg/apis/runtime/v1/api.proto
Introducing Container Runtime Interface (CRI) in Kubernetes: https://kubernetes.io/blog/2016/12/container-runtime-interface-cri-in-kubernetes/
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
dbaplus Community
Enterprise-level professional community for Database, BigData, and AIOps. Daily original articles, weekly online tech talks, monthly offline salons, and quarterly XCOPS&DAMS conferences—delivered by industry experts.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
