Migrating from Docker To Containerd
Published: 2023-12-26 14:35:04

_In the dynamic world of container orchestration, choosing the right container runtime is crucial for optimizing performance and resource utilization. If you've been using Docker and are contemplating a switch, this blog post will guide you through the process of migrating to Containerd. Follow this step-by-step guide to ensure a smooth migration and unlock the benefits that Containerd has to offer._

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w3csf0ud6z9ue2cpuxoj.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6tox504v7r97wf7o05uw.png)

**Understanding the Basics**
_Containerd Overview:_
Containerd serves as an essential building block for higher-level container platforms, including Docker and Kubernetes. Initially developed by Docker, Inc., it was later contributed to the community and is now a standalone project within the Cloud Native Computing Foundation (CNCF). Containerd's design emphasizes simplicity, portability, and extensibility, making it a versatile solution for various containerization needs.

**Key Features**

**Container Lifecycle Management:**
_Containerd excels in managing the entire lifecycle of containers, handling tasks such as image transfer, container execution, and storage management. It abstracts away the complexities of these operations, providing a standardized interface for container runtimes._

**Image Distribution:**
_Containerd supports the distribution and management of container images. It interfaces with container registries to efficiently pull, push, and store container images, ensuring seamless deployment across diverse environments._

**Pluggable Architecture:**
_With a modular and pluggable architecture, Containerd allows users to customize and extend its functionality. This flexibility enables integrations with various container orchestration systems and supports a diverse range of use cases._

**Runtime Interface:**
_Containerd adheres to the container runtime interface (CRI), making it compatible with container orchestration platforms like Kubernetes. Its compliance with industry standards enhances interoperability and ease of integration into existing container ecosystems._

**Architecture:**
_Containerd's architecture is designed with a focus on simplicity and modularity. The key components include:_

**Shim Layer:**
_The shim layer serves as the intermediary between the container runtime and the container process. It helps in handling container execution, managing process lifecycle, and interfacing with the underlying operating system._

**Containerd Daemon:**
_The core daemon manages essential container operations such as image handling, storage management, and container lifecycle. It exposes a gRPC API that enables communication with client applications and container runtimes._

**gRPC API:**
_Containerd's gRPC API provides a standardized and efficient communication channel for interacting with the daemon. It allows seamless integration with client tools, container orchestrators, and other components in the container ecosystem._


**Migrate Kubernetes from Docker to Containerd**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/53lrr7gjd9ndy1skexxg.png)

_Kubernetes decided to deprecate Docker as container runtime after v1.20_

_Explanation of why Kubernetes decided to deprecate Docker can be found here: [Reason Of Deprecate Docker](https://kubernetes.io/blog/2020/12/02/dont-panic-kubernetes-and-docker/)_

_In this post, we are going to migrate Kubernetes cluster from Docker to Containerd. These changes will apply to all nodes in the cluster. I recommend starting migrating from worker nodes._

**Prepare node**
_First of all, scheduling must be disabled and all unnecessary workloads, except daemon sets, must be evicted._

_- Start by cordoning the node_

```
$ kubectl cordon k8s-worker-3
node/k8s-worker-3 cordoned
```

_- Drain node_

```
$ kubectl drain k8s-worker-3 --ignore-daemonsets --delete-emptydir-data
node/k8s-worker-3 already cordoned
node/k8s-worker-3 evicted
```

_- Stop Kubelet and docker_

```
$ systemctl stop kubelet
$ systemctl stop docker
```

**- Switch to containerd**

_Node is ready to be migrated to containerd. Start by removing docker as it will not be needed anymore_

```
$ apt purge docker-ce docker-ce-cli
```
_Ensure containerd is installed_

```
$ ctr -n moby container list
```
_Ensure that config file for containerd in /etc/containerd/config.toml is present. You can generate it with_

```
$ mkdir -p /etc/containerd
$ containerd config default | sudo tee /etc/containerd/config.toml
```
_If you are using the systemd as a cgroup driver, you must configure it in containerd config. In /etc/containerd/config.toml Add_

```
<...>
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  <...>
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true # <--- This line
<...>
```
_Restart containerd_

```
$ systemctl restart containerd
$ systemctl status containerd
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pmrl2iy7n1d24zmzyz92.png)

_Edit /var/lib/kubelet/kubeadm-flags.env file by adding container runtime flags_
    --container-runtime=remote
    --container-runtime-endpoint=unix:///run/containerd/containerd.sock

_kubeadm-flags.env file should now look something like this_

```
$ cat /var/lib/kubelet/kubeadm-flags.env
KUBELET_KUBEADM_ARGS="--network-plugin=cni --pod-infra-container-image=k8s.gcr.io/pause:3.2 --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock"
```
_Start Kubelet_

```
$ systemctl start kubelet
$ systemctl status kubelet
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0u5i7l4x07rr8evm8spl.png)![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/idtu6bx9rk2u1tm7o11l.png)

_Check cluster status_

```
$ kubectl get nodes
```
_Uncordon the node if everything looks good_

```
$ kubectl uncordon k8s-worker-3
```

> Repeat the procedure for all nodes (one by one) and in last master node.

**Post-migration**
 _Let's free up some space by removing docker-related folders. They will not be needed anymore_

```
$ rm -r /etc/docker
$ rm -r /var/lib/docker
$ rm -r /var/lib/dockershim
```
_If you are using kubeadm to manage your cluster initialization, joins, and updates, you might want to re-annotate nodes, so kubeadm will not get confused on your next update whether you are using docker or containterd as a runtime_

```
$ kubectl annotate node k8s-worker-3 --overwrite kubeadm.alpha.kubernetes.io/cri-socket=unix:///run/containerd/containerd.sock
```

> Note that removals and annotate must be executed on all nodes after the whole cluster will be migrated to containerd and ensured that the migration was successful.