Infrastructure at your Service

Jean-Philippe Clapot

Kubernetes : from Docker to containerd

Kubernetes is very popular and well-known open-source orchestration platform for containers. Very dynamic ecosystem, the release cycle is also very fast.
Six months passed since the K8s team announced the dockershim will be deprecated and the 1.22 release deadline is approaching.
As they informed in their quite detailed post in early Dec. 2020, Docker support will be removed in 1.22 :
We are here today in order to see how we can migrate, with minimal overhead, a Kubernetes cluster setup to use Docker as container runtime into a up-to-date cluster using containerd instead, and ready for future releases.

From Docker to containerd migration

This cluster is setup on latest Ubuntu LTS release, 20.04.2, but steps described here are easily adaptable to other Linux flavors, like RedHat or CentOS.

We are going to proceed first with the workers and then the master.

Let’s drain the worker1.

Move to worker1 now.
When you installed Docker on your nodes, containerd was installed too.
To confirm that statement, you can try to check the containerd service status.

Before doing any activity, stop kubelet :

When installed through Docker, containerd got its CRI plugin disabled.
Update its config file accordingly which sits in /etc/containerd/config.toml and comment the line containing disabled_plugins = [“cri”]

Once the configuration is updated, restart the containerd service.

Now it’s time to update kubelet to tell him to use containerd as CRI runtime instead of Docker. For that purpose, two arguments were implemented.
When you navigate to the kubelet reference page on the official website, you’ll get a better overview :

We would need to update both (note kubelet defaulting to Docker !)

New arguments values would be for containerd :
--container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock

Those arguments are defined the kubelet drop-in file for systemd. Open the /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
Check the content. On default installations, the KUBELET_EXTRA_ARGS is not defined, you would need to add it as a new line in the file. Your updated configuration file should be similar to the following :

Inform systemd we’ve updated the configuration and restart the kubelet.

If the systemctl daemon-reload is not performed, you’ll be warned by the system:

To summarize : we’ve updated containerd to be ready to be used as CRI runtime, we’ve told kubelet to use containerd instead of Docker. Time is now to switch back to the master, check if things have changed and move on !

Surprise ! Well, not a suprise because we expected this : Kubernetes is reporting now that our worker1 node is running on containerd instead of Docker. Pay attention to the last column.

We are ready now to bring back the worker1 into the cluster. For that, you need to uncordon :

Repeat this with worker2, and then master, and you’ll be ready.

Our cluster is fully operational, using containerd :

Leaving Docker installed ?

Note that with the activities we performed here, we left Docker installed on each nodes. containerd was installed as a part of the installation of Docker.
If you plan to remove Docker completely, you would need to install containerd as a standalone package. This can be done using package through the standard Docker repository.
Another solution is to download containerd binaries from the official website:
In that case, you may need to generate the containerd config file using the command:
containerd config default > /etc/containerd/config.toml

The ctr command

Now we don’t use anymore docker, the docker cli command won’t list any container. By using containerd, we can now use the ctr command, the containerd cli tool used to interact with containerd.
Like with docker, with the ctr command, you can list / create / delete containers, import / export / pull images, and many more.

Note the namespace terminology here. Namespaces in containerd are not the same namespaces used in Kubernetes.

With ctr, you can also list pulled images:


By migrating your cluster away from docker, you’ll be protected against the deprecation of one of the core component, scheduled in the upcoming release.
But containerd also provide additional flexibility.
In a second episode, we will learn how to setup Kubernetes to use containerd, with not only runC as OCI runtime but also KataContainers.
Stay connected !

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Jean-Philippe Clapot
Jean-Philippe Clapot