Lesson 9: Setting Up Container Runtime
Building a production-ready Kubernetes cluster from scratch / Preparing the Environment for Kubernetes
In this lesson, we will set up containerd as the container runtime on each Raspberry Pi device. Containerd is a lightweight and efficient container runtime that is widely used in Kubernetes environments due to its simplicity and compatibility with Kubernetes’ container runtime interface (CRI).
This is the 9th lesson of the guide Building a production-ready Kubernetes cluster from scratch. Make sure you have completed the previous lesson before continuing here. The full list of lessons in the guide can be found in the overview.
sudo
privileges.
Either prepend sudo
to each command or switch to the root user using sudo -i
.
Preparing the NVMe Directory
First, create the directory where containerd will be installed:
$ mkdir -p /mnt/nvme/containerd
Installing containerd on Each Raspberry Pi
To begin, make sure you are connected to each Raspberry Pi via SSH. Perform the following steps on each device:
Update the package list and install required dependencies:
$ apt update
$ apt install -y apt-transport-https curl gnupg2 software-properties-common
Next, install containerd:
$ apt install -y containerd
Configuring containerd
Once containerd is installed, we need to configure it properly to work with Kubernetes and use the NVMe drive.
First, stop the containerd service:
$ systemctl stop containerd
Create a default configuration file for containerd:
$ mkdir -p /etc/containerd
$ containerd config default | tee /etc/containerd/config.toml
Configuring containerd Storage and Runtime
Now we’ll modify the configuration to use the NVMe drive for storage for any persistent data and configure the system
cgroup driver. Open the configuration file with a text editor like vim
or nano
:
$ vim /etc/containerd/config.toml
At the top of the file, find the line that specifies the root
setting which is the directory where containerd will
store its data:
root = "/mnt/nvme/containerd"
Change the value to the path of the NVMe drive:
root = "/mnt/nvme/containerd"
Configuring containerd for Kubernetes
We need to configure the system cgroup driver to systemd
because we are using the systemd
cgroup driver. cgroup
is
a Linux kernel feature that limits the resources that can be used by a process.
In the same section as the root
setting, we need to configure the SystemdCgroup
setting to true
:
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
Save the changes and exit the editor (in vi
, press Esc
followed by :wq
and Enter
).
Starting containerd Service
Restart containerd to apply the configuration changes and enable it to start on boot:
$ systemctl enable containerd
$ systemctl restart containerd
Verifying containerd Installation
To confirm that containerd is installed and configured correctly, check the status of the containerd service:
$ systemctl status containerd
● containerd.service - containerd container runtime
Loaded: loaded (/lib/systemd/system/containerd.service; enabled; preset: enabled)
Active: active (running) since Sun 2025-01-12 20:16:00 CET; 21s ago
Docs: https://containerd.io
Main PID: 4629 (containerd)
Tasks: 10
CPU: 86ms
CGroup: /system.slice/containerd.service
└─4629 /usr/bin/containerd
Jan 12 20:16:00 kubernetes-node-1 containerd[4629]: time="2025-01-12T20:16:00.483721289+01:00" level=info msg="Start subscribing containerd event"
Jan 12 20:16:00 kubernetes-node-1 containerd[4629]: time="2025-01-12T20:16:00.483770622+01:00" level=info msg="Start recovering state"
Jan 12 20:16:00 kubernetes-node-1 containerd[4629]: time="2025-01-12T20:16:00.483840678+01:00" level=info msg="Start event monitor"
Jan 12 20:16:00 kubernetes-node-1 containerd[4629]: time="2025-01-12T20:16:00.483866549+01:00" level=info msg="Start snapshots syncer"
Jan 12 20:16:00 kubernetes-node-1 containerd[4629]: time="2025-01-12T20:16:00.483879086+01:00" level=info msg="Start cni network conf syncer for default"
Jan 12 20:16:00 kubernetes-node-1 containerd[4629]: time="2025-01-12T20:16:00.483890030+01:00" level=info msg="Start streaming server"
Jan 12 20:16:00 kubernetes-node-1 containerd[4629]: time="2025-01-12T20:16:00.484237568+01:00" level=info msg=serving... address=/run/containerd/containerd.sock.ttrpc
Jan 12 20:16:00 kubernetes-node-1 containerd[4629]: time="2025-01-12T20:16:00.484282883+01:00" level=info msg=serving... address=/run/containerd/containerd.sock
Jan 12 20:16:00 kubernetes-node-1 systemd[1]: Started containerd.service - containerd container runtime.
Jan 12 20:16:00 kubernetes-node-1 containerd[4629]: time="2025-01-12T20:16:00.485584240+01:00" level=info msg="containerd successfully booted in 0.038755s"
To verify that containerd is using the NVMe drive for storage, check the log output of the containerd service:
$ journalctl -u containerd
...
Mar 16 16:40:53 kubernetes-node-1 containerd[20982]: time="2025-03-16T16:40:53.491421451+01:00" level=info msg="Connect containerd service"
Mar 16 16:40:53 kubernetes-node-1 containerd[20982]: time="2025-03-16T16:40:53.491479507+01:00" level=info msg="Get image filesystem path \"/mnt/nvme/containerd/io.containerd.snapshotter.v1.overlayfs\""
...
The output should show that the containerd service is active and running, now using the NVMe drive for storage.
Lesson Conclusion
Congratulations! With containerd installed and configured, your Raspberry Pi devices are now ready to run containers as part of the Kubernetes cluster. You have completed this lesson and you can now continue with the next one.
I strive to create helpful and accurate content, but there's always room for improvement! Whether you notice a typo, have ideas to make this clearer, or want to share your thoughts, I warmly welcome your feedback. Together, we can make this content even better for everyone.
Edit this page | Create an issue