Mirantis cri-dockerd is an adapter created to provide a shim for Docker Engine to let you control Docker Engine via the Kubernetes Container Runtime Interface. I know most of you by now are aware that Kubernetes has deprecated Docker as a container runtime after v1.20. This was as a result of Kubernetes Development decision to deprecate Docker as an underlying runtime in favor of runtimes that use the Container Runtime Interface (CRI) created for Kubernetes. However, Docker-produced images will continue to work in your Kubernetes cluster with all runtimes, as they always have. For any container engine that is CRI compliant, it can run in Kubernetes with no extra effort.
But it’s not the end of the world, and you don’t need to panic. What you just need is to change your container runtime from Docker to another supported container runtime. Mirantis and Docker came into rescue by agreeing to partner in the maintenance of the shim code standalone. This code is maintained outside Kubernetes, as a conformant CRI interface for the Docker Engine API. The cri-dockerd makes Docker Engine to be CRI compliant and you can continue to use it in your Kubernetes by just switching from the built in dockershim to the external one.
Setup cri-dockerd as Docker Engine shim for Kubernetes
We will start with the installation of cri-dockerd and demonstrate how one can use it in Kubernetes. A “shim” is used to translate between the Docker Engine component and the relevant Kubernetes interface, in this case Container Runtime Interface (CRI). If you need a CRI compliant Engine, you can easily switch to Containerd and eliminate the need for cri-dockerd interface.
It is worth mention that all the images you create using docker build are compliant with the underlying standard CRI use. The container images are still going to work well with Kubernetes. Our focus is on replacing deprecated dockershim so that we can make Docker Engine CRI compliant.
Install cri-dockerd on Linux
You can install cri-dockerd on Linux from source using Go, or by downloading ready binaries. We shall consider the two options.
A pre-requisite for this installation is Docker-Engine. You can reference our guide below to install the latest Docker Engine runtime on your Linux machine:
Ensure Docker service is running before you proceed:
$ systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2022-04-15 10:34:54 UTC; 14s ago
Docs: https://docs.docker.com
Main PID: 26072 (dockerd)
Tasks: 9
Memory: 29.1M
CGroup: /system.slice/docker.service
└─26072 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Install cri-dockerd using ready binary (recommended)
Install wget
and curl
command line tools.
### Debian based systems ###
sudo apt update
sudo apt install git wget curl
### RHEL based systems ###
sudo yum -y install git wget curl
### SUSE based Linux ###
sudo zypper install git wget curl
### Arch based Linux ###
sudo pacman -Syy
sudo pacman -S git wget curl
Once the tools are installed, use them to download the latest binary package of cri-dockerd. But first, let’s get the latest release version:
VER=$(curl -s https://api.github.com/repos/Mirantis/cri-dockerd/releases/latest|grep tag_name | cut -d '"' -f 4|sed 's/v//g')
echo $VER
We can then download the archive file from Github cri-dockerd releases page.
### For Intel 64-bit CPU ###
wget https://github.com/Mirantis/cri-dockerd/releases/download/v${VER}/cri-dockerd-${VER}.amd64.tgz
tar xvf cri-dockerd-${VER}.amd64.tgz
### For ARM 64-bit CPU ###
wget https://github.com/Mirantis/cri-dockerd/releases/download/v${VER}/cri-dockerd-${VER}.arm64.tgz
cri-dockerd-${VER}.arm64.tgz
Move cri-dockerd
binary package to /usr/local/bin
directory
sudo mv cri-dockerd/cri-dockerd /usr/local/bin/
Validate successful installation by running the commands below:
$ cri-dockerd --version
cri-dockerd 0.3.4 (e88b1605)
Configure systemd units for cri-dockerd:
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
Start and enable the services
sudo systemctl daemon-reload
sudo systemctl enable cri-docker.service
sudo systemctl enable --now cri-docker.socket
Confirm the service is now running:
$ systemctl status cri-docker.socket
● cri-docker.socket - CRI Docker Socket for the API
Loaded: loaded (/etc/systemd/system/cri-docker.socket; enabled; vendor preset: disabled)
Active: active (listening) since Fri 2023-03-10 10:02:13 UTC; 4s ago
Listen: /run/cri-dockerd.sock (Stream)
Tasks: 0 (limit: 23036)
Memory: 4.0K
CGroup: /system.slice/cri-docker.socket
Mar 10 10:02:13 rocky8.mylab.io systemd[1]: Starting CRI Docker Socket for the API.
Mar 10 10:02:13 rocky8.mylab.io systemd[1]: Listening on CRI Docker Socket for the API.
Install cri-dockerd from source (alternative way)
You can also decide to build cri-dockerd from source.
Install Golang on your system
wget https://storage.googleapis.com/golang/getgo/installer_linux
chmod +x ./installer_linux
./installer_linux
source ~/.bash_profile
Confirm installation by checking version of Go.
$ go version
go version go1.20.5 linux/amd64
Clone the project code from Github repository
git clone https://github.com/Mirantis/cri-dockerd.git
Run the commands below to build this code (in a POSIX environment):
cd cri-dockerd
mkdir bin
cd src && go get && go build -o ../bin/cri-dockerd
cd ..
Finally install cri-dockerd on a Linux system. This assumes your system uses systemd, and Docker Engine is installed.
sudo mkdir -p /usr/local/bin
sudo install -o root -g root -m 0755 bin/cri-dockerd /usr/local/bin/cri-dockerd
sudo cp -a packaging/systemd/* /etc/systemd/system
Start and enable the cri-docker service
sudo sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service
sudo systemctl daemon-reload
sudo systemctl enable cri-docker.service
sudo systemctl enable --now cri-docker.socket
Check service status:
$ systemctl status cri-docker.socket
● cri-docker.socket - CRI Docker Socket for the API
Loaded: loaded (/etc/systemd/system/cri-docker.socket; enabled; vendor preset: disabled)
Active: active (listening) since Fri 2023-03-10 10:02:13 UTC; 2min 9s ago
Listen: /run/cri-dockerd.sock (Stream)
Tasks: 0 (limit: 23036)
Memory: 4.0K
CGroup: /system.slice/cri-docker.socket
Mar 10 10:02:13 rocky8.mylab.io systemd[1]: Starting CRI Docker Socket for the API.
Mar 10 10:02:13 rocky8.mylab.io systemd[1]: Listening on CRI Docker Socket for the API.
From the output we can find out the path to the CRI socket.
Listen: /run/cri-dockerd.sock
For cri-dockerd
, the CRI socket is /run/cri-dockerd.sock
by default.
Configure the kubelet to use cri-dockerd
You should have kubelet installed before you can configure it to use cri-dockerd. The steps shared apply to clusters set up using the kubeadm.
Using cri-dockerd on new Kubernetes cluster
Ensure Docker Engine is installed and running:
systemctl status docker
You should have installed kubeadm and kubelet components as well. With the components installed we can test pulling container images for Kubernetes.
$ sudo kubeadm config images pull --cri-socket /run/cri-dockerd.sock
[config/images] Pulled registry.k8s.io/kube-apiserver:v1.26.2
[config/images] Pulled registry.k8s.io/kube-controller-manager:v1.26.2
[config/images] Pulled registry.k8s.io/kube-scheduler:v1.26.2
[config/images] Pulled registry.k8s.io/kube-proxy:v1.26.2
[config/images] Pulled registry.k8s.io/pause:3.9
[config/images] Pulled registry.k8s.io/etcd:3.5.6-0
[config/images] Pulled registry.k8s.io/coredns/coredns:v1.9.3
Bootstrap Control plane (This is for single node controller)
sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--cri-socket /run/cri-dockerd.sock
The initialization should be successful.
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Container runtime endpoint is configured in /var/lib/kubelet/kubeadm-flags.env
.
$ sudo cat /var/lib/kubelet/kubeadm-flags.env
KUBELET_KUBEADM_ARGS="--container-runtime=remote --container-runtime-endpoint=/run/cri-dockerd.sock --pod-infra-container-image=k8s.gcr.io/pause:3.6"
Migrating existing Nodes from from dockershim to cri-dockerd
Cordon the node. Don’t forget to replace <NODE_NAME>
with the name of the node.
kubectl cordon <NODE_NAME>
Drain the node to safely evict running Pods:
kubectl drain <NODE_NAME> --ignore-daemonsets
Open /var/lib/kubelet/kubeadm-flags.env on each affected node.
sudo vim /var/lib/kubelet/kubeadm-flags.env
Modify the --container-runtime-endpoint
flag to unix:///var/run/cri-dockerd.sock
.
The kubeadm tool stores the node’s socket as an annotation on the Node
object in the control plane. To modify this socket for each affected node:
Edit the YAML representation of the Node
object:
KUBECONFIG=/path/to/admin.conf kubectl edit no <NODE_NAME>
Replace the following:
/path/to/admin.conf
: the path to the kubectl configuration file,admin.conf
.<NODE_NAME>
: the name of the node you want to modify.
Change kubeadm.alpha.kubernetes.io/cri-socket
from /var/run/dockershim.sock
to unix:///var/run/cri-dockerd.sock
.
Save the changes. The Node
object is updated on save and restart kubelet
sudo systemctl restart kubelet
Uncordon the node to let Pods schedule on it:
kubectl uncordon <NODE_NAME>
Books For Learning Kubernetes Administration:
More guides: