Cloud Native 7 min read

Step‑by‑Step Guide to Migrate Kubernetes Nodes from Docker to containerd

This tutorial walks through migrating a two‑node Kubernetes cluster (master and worker) from Docker to containerd on CentOS 7, covering environment setup, node draining, Docker removal, containerd installation and configuration, kubelet adjustments, uncordoning, and verification of the new container runtime.

Full-Stack DevOps & Kubernetes
Full-Stack DevOps & Kubernetes
Full-Stack DevOps & Kubernetes
Step‑by‑Step Guide to Migrate Kubernetes Nodes from Docker to containerd

The lab uses two CentOS 7.6 nodes (xianchaomaster1 as the control‑plane master and xianchaonode1 as a worker) running Kubernetes v1.23.1. Initial checks show both nodes using Docker as the container runtime.

Drain the master node Run:

kubectl drain xianchaomaster1 --delete-emptydir-data --force --ignore-daemonsets

This evicts pods and marks the node as SchedulingDisabled .

Remove Docker and install containerd Disable Docker: systemctl disable docker --now Uninstall Docker packages: yum remove docker-ce docker-ce-cli -y Install containerd and cri‑tools: yum install containerd.io cri-tools -y Configure containerd runtime endpoint:

crictl config runtime-endpoint unix:///var/run/containerd/containerd.sock

Generate the default configuration file: containerd config default > /etc/containerd/config.toml Edit /etc/containerd/config.toml (using vim ) and make three changes:

Set the registry mirror:

[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://rsbud4vc.mirror.aliyuncs.com"]

Set the sandbox image:

sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.7"

Enable systemd cgroup:

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true

Save and exit the file. Restart containerd: systemctl enable containerd ; systemctl restart containerd Configure and restart kubelet Edit /etc/sysconfig/kubelet and add extra arguments so kubelet talks to containerd:

KUBELET_EXTRA_ARGS="--container-runtime=remote \
--runtime-request-timeout=15m \
--container-runtime-endpoint=unix:///run/containerd/containerd.sock"

Restart kubelet: systemctl restart kubelet Uncordon the master node kubectl uncordon xianchaomaster1 Verify the runtime change on the master kubectl get nodes -owide The output should show containerd://1.6.6 for the master.

Repeat the same procedure for the worker node Drain the worker:

kubectl drain xianchaonode1 --delete-emptydir-data --force --ignore-daemonsets

Disable and uninstall Docker, install containerd, generate and edit /etc/containerd/config.toml with the same three sections, restart containerd, configure kubelet with the same extra args, restart kubelet, and finally uncordon the worker: kubectl uncordon xianchaonode1 Verify both nodes now report containerd://1.6.6 as the container runtime.

After completing these steps, the Kubernetes cluster runs entirely on containerd, eliminating Docker and aligning with newer Kubernetes best practices.

KubernetesDevOpscontainerdDocker migration
Full-Stack DevOps & Kubernetes
Written by

Full-Stack DevOps & Kubernetes

Focused on sharing DevOps, Kubernetes, Linux, Docker, Istio, microservices, Spring Cloud, Python, Go, databases, Nginx, Tomcat, cloud computing, and related technologies.

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.