In the past, migrating away from Dockershim in Kubernetes was a challenge. In v1.24 and later, it is much easier. Dockerfiles for Kubernetes can be found on the kubernetes website. The first step is to create a new file called “configs” in your home directory. This file contains your Kubernetes configuration. Next, you need to create a new file called “kube-system” in this same directory. This file contains all of your Kubernetes settings and information. The next step is to add the following line to your configs file: [kubernetes] name = Dockershim cluster = true port = 8088 targetPort = 8088
Kubernetes v1.24 and later releases ship without Dockershim after its deprecation in December 2020’s v1.20 release. Dockershim’s no longer available as a built-in container runtime. You need to use a different supported runtime instead, such as containerd, CRI-O, or Docker Engine with the cri-dockerd adapter.
In this article, we’ll show how to check whether you’re affected, then explain how you can migrate to a different runtime. You should take these steps before you upgrade to Kubernetes v1.24 or a later version so your cluster’s workloads aren’t impacted.
What Was Dockershim?
Dockershim was developed as a necessary component so Kubernetes could support more container runtimes. At the start of the project, Kubernetes only worked with Docker Engine. This restriction was removed by the introduction of the CRI standard. Any CRI-compatible runtime could now be used with Kubernetes, including containerd and CRI-O, an OCI implementation of the standard.
While CRI brought new flexibility to Kubernetes, it presented an issue for existing clusters. Docker lacked support for the CRI standard so Dockershim was built to let the Kubernetes team layer compatibility on top. Dockershim was a direct integration with Docker Engine that was always intended to be a temporary measure.
The container movement is now much more than Docker, as the original Kubernetes push to CRI demonstrates. Docker itself has split into individual components with its runtime extracted as containerd, a graduate of the Cloud Native Computing Foundation (CNCF).
containerd is fully supported by Kubernetes and more suited to standalone use in cloud environments. Kubernetes doesn’t require the Docker CLI and its bevy of features to run your Pods; all it needs is the ability to start and run containers at a relatively low level. Dockershim has been removed because it was difficult to maintain. Its use created fragile code that was tightly coupled to Docker Engine’s implementation.
Checking Whether You’re Using Dockershim
You’re most likely to need to take action if you maintain your own cluster and first set it up several years ago. You can check whether you’re using Dockershim as the runtime for any of your Nodes by running this Kubectl command:
In this example, one of the nodes is using containerd and can be left as-is. The other node is configured using Docker and could be affected by the Dockershim removal. You can check by running this command on the Node:
Your Node is using Dockershim to run containers if no output’s displayed. If you do get some output, inspect the displayed –container-runtime-endpoint flag value to determine if Dockershim is active. A runtime endpoint of unix:///run/containerd/containerd.sock signals containerd is used, so no migration is necessary.
Changing A Node’s Runtime
Nodes that are using Dockershim need to be updated to use a different runtime. First drain the Node’s workloads using Kubectl, so your Pods are rescheduled to other Nodes in your cluster. You should cordon the Node too to stop any new Pods being scheduled.
Next run the following commands on the Node itself. Begin by stopping the Docker daemon and the Node’s Kubelet worker process:
Now you can install your new runtime.
Using containerd
containerd is generally the preferred solution for current clusters. You should be able to migrate to containerd if you’re not relying on specific features of Docker Engine. If you are, head to the following section and install cri-dockerd instead.
Add Docker’s repository to your system if your package lists don’t already include it. containerd is distributed in Docker’s repository.
Install containerd:
Now update the Node’s Kubelet configuration file to use the new runtime. Open /var/lib/kubelet/kubeadm-flags.env. Look for or add the –container-runtime and –container-runtime-endpoint flags with the following values:
–container-runtime=remote –container-runtime-endpoint=unix:///run/containerd/containerd. sock
Next change the socket annotation saved against the Node object in the Kubernetes control plane:
In the file that opens, find the kubeadm.alpha.kubernetes.io/cri-socket annotation and change it to unix:///run/containerd/containerd.sock. Save and close the file to update the Node’s object.
Now restart Kubelet:
Allow the Node a few moments to start and connect to the Kubernetes control plane. You should be able to repeat the get nodes command and see that containerd is now being used.
Finally remove the cordon you placed around the Node so it can begin to receive Pods:
Using cri-dockerd
cri-dockerd is a runtime jointly developed by Docker and Mirantis. It’s effectively a standalone version of Dockershim that’s independently maintained. It allows you to keep using familiar functionality without encumbering the Kubernetes project with Dockershim’s maintenance requirements.
Make sure you’ve already got Docker Engine installed. Then install cri-dockerd by downloading the latest binary from GitHub releases:
Next download, install, and enable cri-dockerd’s systemd service configurations:
Now you can modify your Node’s Kubelet configuration to use cri-dockerd. This is similar to configuring a Node to use containerd.
Open /var/lib/kubelet/kubeadm-flags.env. Look for or add the –container-runtime and –container-runtime-endpoint flags with the following values:
–container-runtime=remote –container-runtime-endpoint=unix:///var/run/cri-dockerd. sock
Next change the Node object’s socket annotation:
In the file that opens, find the kubeadm.alpha.kubernetes.io/cri-socket annotation and change it to unix:///var/run/cri-dockerd.sock. Save and close the file to update the Node’s object.
Now restart Kubelet:
Wait a few moments and then use Kubectl to check the Node is up. It will still show the Docker runtime but it’s now based on the standalone cri-dockerd, instead of the Dockershim that’s integrated with Kubernetes.
You can now remove the cordon you placed around the Node. It will start to accept Pod scheduling requests again.
Conclusion
Kubernetes v1.24 removed the Dockershim component that previously integrated CRI compatibility for Docker Engine. While most recent clusters will be unaffected, you should check whether you’re using Dockershim before upgrading to the new release.
The runtime to switch to depends on how you currently use your cluster. containerd is usually a good choice if you’re not using Docker features. You can use cri-dockerd to bring back Dockershim-like integration if you need to maintain compatibility with existing tooling that’s reliant on Docker Engine. This also helps if you’re mounting the Docker daemon socket (/var/run/docker.sock) into your containers to power Docker-in-Docker workflows.
Dockershim’s removal doesn’t impact how you build and use container images. Kubernetes can still run images created with docker build and they’re compatible with all supported runtimes. CRI runtimes work with any OCI-format image, as output by Docker and other image builders.