Mirantis acquires amazee.io, the only ZeroOps Application Delivery Hub.   Read Blog Post  |  View Press Release  |  Visit amazee.io

How to install cri-dockerd and migrate nodes from dockershim

Eric Gregory - July 14, 2022

As of Kubernetes 1.24, dockershim is no longer part of the Kubernetes core. If you’re not quite sure what that means, check out our FAQ for a breakdown of what has changed, what hasn’t, and why it matters.

For most developers, the deprecation of dockershim isn’t a big deal: Docker-built containers will continue to work just the same as before. But the change does mean that users who want to continue using Docker-specific features in their clusters will need to migrate to the cri-dockerd adapter. 

What is cri-dockerd? It’s an open source, CRI-conformant replacement for dockershim, maintained outside of the Kubernetes core by Mirantis, Docker, and the open source community. (If you’re not sure exactly what “dockershim” or “CRI” means, I recommend reading the aforementioned FAQ post.) Mirantis uses cri-dockerd in Mirantis Kubernetes Engine, and Docker does the same in Docker Desktop. Ultimately, cri-dockerd enables users or agents to control Docker Engine through the Kubernetes Container Runtime Interface.

If your cluster is using Docker Engine with dockershim as its container runtime, one option is to manually install cri-dockerd and migrate your nodes to stop using dockershim and start using cri-dockerd. (Alternatively, we can help you make the move.) 

In this post, we’ll walk you through the process to:

  • Install cri-dockerd

    • Start the service on Linux

    • Start the service on Windows

  • Cordon and drain dockershim-dependent nodes

  • Configure nodes to use cri-dockerd 

How to install cri-dockerd on a node

This walkthrough assumes Docker Engine is already installed and running. You can use cri-dockerd with Linux or Windows Server nodes. Start by downloading the appropriate binary package from the cri-dockerd GitHub page.

On Linux, you can use wget:

$ wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.0/cri-dockerd-v0.2.0-linux-amd64.tar.gz

In PowerShell on Windows Server, you can use Invoke-WebRequest. 

> Invoke-WebRequest -Uri https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.0/cri-dockerd-v0.2.0-windows-amd64.zip -UseBasicParsing -o cri-dockerd.zip

Next, unzip the package. On Linux you can use:

$ tar xvf cri-dockerd-v0.2.0-linux-amd64.tar.gz

On Windows Server:

> Expand-Archive -LiteralPath cri-docker.zip -DestinationPath .

If you’re on Linux, move the cri-dockerd binary to your usr/local/bin directory:

$ sudo mv ./cri-dockerd /usr/local/bin/ 

On Windows, you can move the binary to your \Windows\System32 folder, or otherwise include it in your PATH: 

> Move-Item -Path cri-dockerd.exe -Destination C:\Windows\System32

Check to see if it is successfully installed:

$ cri-dockerd --help

You should see the help output explaining the flags you can use with the tool.

Start the service on Linux

Now you’ll need to configure systemd:

$ wget https://raw.githubusercontent.com/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.service
$ wget https://raw.githubusercontent.com/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.socket
$ sudo mv cri-docker.socket cri-docker.service /etc/systemd/system/
$ sudo sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service

…and start the service with cri-dockerd enabled:

$ systemctl daemon-reload
$ systemctl enable cri-docker.service
$ systemctl enable --now cri-docker.socket

You can verify that the service is running with:

$ systemctl status cri-docker.socket

Start the service on Windows

You can start cri-dockerd as a service on a Windows node using nssm.

If you have nssm installed, enter in PowerShell:

> nssm install cri-dockerd

Select the cri-dockerd executable (in C:\Windows\System32 or wherever it is located on your system). And then:

> nssm start cri-dockerd

You can check the service status with:

> nssm status cri-dockerd

Cordon and drain dockershim-dependent nodes

Now we’re going to cordon our node, which does exactly what it sounds like: we’re putting up warning tape around this node and telling the rest of the system not to schedule new pods here. 

$ kubectl cordon <NODE>

…where <NODE> is the name of the node in question (without the angle brackets). 

Next we’re going to drain the node, which means that we will safely and methodically kick out any currently running pods. 

$ kubectl drain <NODE> --ignore-daemonsets

With our node cordoned and drained, we can move on to configure the node to use cri-dockerd. 

Configure nodes to use cri-dockerd

Here, we’ll assume we’ve used kubeadm to configure our node. Use your text editor of choice to open the node’s kubeadm-flags.env file—I’m using nano in the example below. 

$ nano /var/lib/kubelet/kubeadm-flags.env

Inside the file, change the value of the --container-runtime-endpoint flag to: 


Save the file. Next, we’ll need to update the Node object in the control plane. 

$ KUBECONFIG=/path/to/admin.conf kubectl edit no <NODE>

Again, <NODE> is the name of the node in question (without the angle brackets). Replace the file directory path with the appropriate path on your system, leading to the admin.conf configuration file.

Within the file, modify kubeadm.alpha.kubernetes.io/cri-socket from /var/run/dockershim.sock to unix:///var/run/cri-dockerd.sock.

Finally, save the changes. At this point, we can restart the kubelet:

$ systemctl restart kubelet

Verify that the node is using the correct adapter by running:

$ kubectl describe <NODE>

Under the annotations section, you should see a value specifying that the node uses cri-dockerd.sock. Now uncordon the node, and you’re done!

$ kubectl uncordon <NODE>

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