Meet k0smotron 1.0 - the future of Kubernetes cluster management   Learn More


FAQ: What’s the deal with dockershim and cri-dockerd?


This webinar presentation offers a more complete explanation of cri-dockerd vs. dockershim, and illustrates how cri-dockerd will help standardize container workflows on Kubernetes.

With the release of Kubernetes 1.24, dockershim is no longer a part of the Kubernetes core. That means users who wish to upgrade to 1.24 while using Docker as a container runtime in their clusters need an alternative solution. 

The good news is that Mirantis and Docker are maintaining an open source, fully CRI-conformant third-party adapter: cri-dockerd

If you’re confused about exactly what all of this means, you’re not alone. The most important things to understand are: 

  • Docker-built containers still work on Kubernetes

  • Developers should see few to no changes in workflow—the differences are on the cluster side

  • We can help you update your cluster—either to continue using Docker Engine as your runtime or to switch to a new one

Want more detail? We’ve put together this short guide to explain exactly what has changed–and what hasn’t. 

Will Docker-built containers still run in Kubernetes?

Yes. If you’re a developer, the containers you build with Docker Engine or Docker Desktop on your dev machine will run on a Kubernetes cluster just the same as before. 

The deprecation in Kubernetes 1.24 doesn’t affect container compatibility. Instead, it refers to the components used by Kubernetes nodes: the physical or virtual machines handling containerized workloads. Specifically, we’re talking about the container runtime, a component that exists on every single node in a cluster, whether you have one node or a hundred.

What is a Kubernetes container runtime?

Kubernetes coordinates a set of machines running containerized workloads, but the container runtime is the component that actually runs those containers on a given node.

Originally, Kubernetes was designed to use Docker Engine as the runtime. That made sense, with Docker being the industry standard. But the Kubernetes system needed an engine block for containers, and Docker was an entire car. A number of Docker Engine’s features were designed for end-users—for developers—not a system that ran containers via API. While some Kubernetes admins might make use of the rest of the car, others would want slimmed down options with fewer moving parts. Meanwhile, Docker Engine was in an awkward position, expected to serve the needs of both end-users and a system like Kubernetes. 

The Docker community started working to spin out containerd, which began life as a runtime manager for the runc component at the heart of Docker Engine. (In other words, the engine block.) In 2016, containerd was integrated with Docker. We’ll come back to it in a moment. Around the same time, the Kubernetes project was hard at work defining a Container Runtime Interface (CRI) to give users more choice when it came to container runtimes.

What is the Container Runtime Interface?

The CRI is an abstraction that standardizes the way different container runtimes interact with Kubernetes—specifically, how those runtimes interact with another node component called the kubelet. This abstraction layer makes it much easier to integrate different runtimes with Kubernetes (or to develop new runtimes), and it brings users greater flexibility. 

There’s a bit of irony here: the deprecation of dockershim has caused some consternation about compatibility since it was announced, but it’s part of a larger initiative for modularity and standardization among container runtimes in Kubernetes…the very reason that everything will keep running smoothly for developers.

What is dockershim?

Originally, Docker Engine was integrated directly with the kubelet code. Once the Kubernetes system moved to use the CRI abstraction layer, there was a complication: Docker Engine pre-dated CRI, and so of course it didn’t conform to the CRI’s standards. To solve the problem, the project added a new component called dockershim that would act as an adapter between the CRI and Docker Engine. 

This was a somewhat awkward fit for a first-party component: a one-off piece of code dedicated to one potential usage pattern. But it was clear that this was a temporary fix (hence the word “shim”), because the folks working on containerd were busy making sure that it would conform with the CRI. 

Okay, so what is containerd, exactly?

Today, containerd is a portable, CRI-conformant, open source container runtime. It is not designed for end-user interaction. Instead, it’s built as a component to be used by higher-level systems. Docker Engine uses it, and it’s a runtime option for Kubernetes. In 2017, it was donated to the Cloud Native Computing Foundation. 

For Kubernetes users who just want an engine block for their runtime, containerd is a good choice. Users migrating existing clusters with complex configurations can contact us for assistance. 

Of course, some users will want to retain access to the whole car. For those users, Mirantis and Docker have partnered to maintain a replacement for dockershim: cri-dockerd.

What is cri-dockerd?

cri-dockerd is an open source adapter that provides fully CRI-conformant compatibility between Docker Engine and the Kubernetes system. It is maintained externally from the core Kubernetes project, through a joint effort by Mirantis, Docker, and the open source community. It is used in Docker Desktop and Mirantis Kubernetes Engine, as well as with Mirantis Container Runtime. The cri-dockerd adapter is a stable, narrowly scoped, and reliably maintained project to replace the stopgap solution of dockershim.

Why might I want to use Docker Engine as my runtime via cri-dockerd?

By design, containerd and alternative runtimes aren’t end-user facing, so they lack some of the commands and functionality of Docker Engine, such as the ability to…

  • Use Docker commands like docker inspect, docker ps, or docker exec

  • Run scripts based on commands specific to Docker Engine

  • Run Docker commands in privileged pods

  • Utilize Docker-specific logging and monitoring

Since these features have been historically available, some organizations have made use of them and may wish to continue doing so. Whether they are relevant for you is a matter of your cluster configuration, workloads, and specific needs.

How do I find out which container runtime my cluster is using?

Using kubectl, you can check your container runtime using the following command:

% kubectl get nodes -o wide

The tenth column in the output will show you the container runtime for each node:


Using Lens, you can click on the Nodes tab and select any node to view status and configuration details, including the container runtime.

How do I install cri-dockerd?

If you wish to manually switch your Docker Engine nodes to use cri-dockerd, you can follow the instructions here. Alternatively, we can help you accomplish this across any cluster.

Which runtime should I use? Should I switch? 

The right answer depends entirely on who you are, what you’re doing, and what brings you value. We can work with you to understand your priorities, then help you use cri-dockerd, upgrade, or switch runtimes according to your needs. 

Need help with Kubernetes migration and upgrades, or want to explore a fully managed Kubernetes solution? Contact us today.

Choose your cloud native journey.

Whatever your role, we’re here to help with open source tools and world-class support.



Cloud Native & Coffee

Subscribe to our bi-weekly newsletter for exclusive interviews, expert commentary, and thought leadership on topics shaping the cloud native world.