Cloud Native 9 min read

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.

dbaplus Community
dbaplus Community
dbaplus Community
Why Kubernetes Dropped Docker’s Dockershim: A Deep Dive into CRI and Runtime Flexibility

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/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Cloud NativeDockerKubernetesCRIDockershim
dbaplus Community
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.