Tutorial: Explore Container Runtimes with Flatcar Container Linux

This tutorial is the second part of a series on Flatcar Container Linux, in which we will get familiar with the container runtimes. It also introduces the concept of running a custom version of containerd runtime as a systemd unit file.
Flatcar Linux instances can be launched in mainstream cloud platforms, including Amazon Web Services, Microsoft Azure, and Google Cloud. We will choose Equinix Metal, which gives us the flexibility to run the OS in the bare metal environment.
After signing up with Equinix Metal, we will launch a new on-demand server instance in the nearest supported region.
I chose the Singapore region, and the x1.small.x86
server configuration.
Next, give your instance a name, associate one of the registered SSH keys, and click on the deploy now button.
Within a few minutes, the server will be ready. You can track the progress in the sidebar of the console.
You can customize the instance by adding cloud-init data in YAML format.
Once the instance is ready, copy the IP address to SSH into it.
Exploring Docker Engine
Flatcar Container Linux supports all of the popular methods for running containers. We can choose to interact with the containers at a low-level, or use a higher-level orchestration engine, which is Kubernetes.
Every Flatcar Container Linux instance comes with a stable version of Docker CE and Docker CLI.
The Docker service gets started as soon as the Docker Socket is activated. You can find the systemd unit files, docker.service
and docker.socket
at /run/systemd/system
directory.
If you want to run the Docker service all the time without having to wait for the socket activation, add the following to the user data. This configuration will help when you want to keep running containers with the restart
attribute set to always
.
1 2 3 4 5 6 |
systemd: units: - name: docker.socket enabled: false - name: docker.service enabled: true |
Exploring the containerd Runtime
Flatcar Container Linux comes with the containerd CRI plugin, and Dockershim enabled by default. Let’s explore that further by downloading the crictl
CLI tool.
1 2 3 |
VERSION="v1.20.0" wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /opt/bin |
We copied the binary to /opt/bin
since /usr/bin
is a part of the read-only filesystem.
Assuming Docker service is up and running, we can connect to the Dockershim endpoint through with crictl
.
1 |
sudo crictl --runtime-endpoint=unix:///run/docker/libcontainerd/docker-containerd.sock version |
Installing and Configuring a Custom containerd Runtime
It is possible to replace default Docker and containerd runtimes with custom versions. In this example, we will run containerd 1.4.1 instead of the default version, 1.4.3.
Let’s download the containerd 1.4.1 binary and move it to /opt/bin
directory.
1 |
wget https://github.com/containerd/containerd/releases/download/v1.4.1/containerd-1.4.1-linux-amd64.tar.gz |
1 |
tar xvf containerd-1.4.1-linux-amd64.tar.gz && sudo mv bin/containerd /opt/bin |
We will create an empty file that will act as the placeholder for the configuration.
1 2 |
sudo mkdir -p /etc/containerd/ sudo touch /etc/containerd/config.toml |
Create a systemd unit file with the below content. We are calling this containerd141.service
to avoid the conflict with the current runtime configuration.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
sudo bash -c 'cat << EOF > /etc/systemd/system/containerd141.service [Unit] Description=containerd container runtime After=network.target [Service] Environment=CONTAINERD_CONFIG=/etc/containerd/config.toml Environment=PATH=/opt/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin ExecStart= ExecStart=/opt/bin/containerd --config /etc/containerd/config.toml KillMode=process Restart=always LimitNOFILE=1048576 LimitNPROC=infinity LimitCORE=infinity TasksMax=infinity [Install] WantedBy=multi-user.target EOF' |
Before activating this, let’s stop Docker and container containerd services.
1 2 |
sudo systemctl stop docker sudo systemctl stop containerd |
Let’s activate the containerd 1.4.1 service.
1 2 |
sudo systemctl enable /etc/systemd/system/containerd141.service sudo systemctl start containerd141 |
We can now test the version of the runtime with the crictl
tool.
1 |
sudo crictl --runtime-endpoint unix:///run/containerd/containerd.sock version |
Notice that we are using the native socket of containerd instead of the Dockershim.
To initialize a custom version of containerd during the boot process, we can embed it in the Ignition file’s configuration, which we will explore in the next part of the series. Stay tuned.
Janakiram MSV’s Webinar series, “Machine Intelligence and Modern Infrastructure (MI2),” offers informative and insightful sessions covering cutting-edge technologies. Sign up for the upcoming MI2 webinar at http://mi2.live.
Feature image by Russ Ward on Unsplash.