CRI-O as a replacement for Docker as the runtime for Kubernetes: setting up on CentOS 8

Hello! My name is Sergey, I am DevOps at Surf. The DevOps department at Surf aims not only to establish interaction between specialists and integrate work processes, but also to actively research and implement relevant technologies both in its own infrastructure and in the customer’s infrastructure.

Below I will talk a little about the changes in the technological stack for containers that we met while studying the distribution. CentOS 8 and what is CRI-O and how to quickly set up an executable environment with it for Kubernetes

Why Docker is missing from the standard CentOS 8 distribution

After installing the latest major releases RHEL 8 or CentOS 8 it is impossible not to notice: there is no application in these distributions and official repositories Docker, which ideologically and functionally replace packages Podman, Buildah (present in the default distribution) and CRI-O… This is due to the practical implementation of standards developed, among other things, by Red Hat as part of the Open Container Initiative (OCI).

The goal of OCI, which is part of The Linux Foundation, is to create open industry standards for container formats and runtimes that address multiple challenges. First, they did not contradict both the Linux philosophy (for example, in that part of it that each program should perform some one action, and Docker is a kind of all-in-one harvester). Secondly, we could eliminate all existing flaws in the software. Docker… Third, they would be fully compliant with the business requirements of leading commercial platforms for deploying, managing and serving containerized applications (for example, Red Hat OpenShift).

disadvantages Docker and the advantages of the new software have already been described in some detail in this article, and a detailed description of how the entire software stack offered within the OCI project and its architectural features can be found in the official documentation and articles from both Red Hat itself (not bad article in the Red Hat blog) and third-party reviews.

It is important to note what functionality the components of the proposed stack have:

  • Podman – direct interaction with containers and image storage through the runC process;
  • Buildah – assembly and loading into the register of images;
  • CRI-O – an executable environment for container orchestration systems (for example, Kubernetes).

I think that in order to understand the general scheme of interaction between the components of the stack, it is advisable to give a connection diagram here Kubernetes c runC and low-level libraries using CRI-O:

CRI-O and Kubernetes adhere to the same release and support cycle (the compatibility matrix is ​​very simple: major releases Kubernetes and CRI-O coincide), and this, taking into account the focus on full and comprehensive testing of the work of this stack by developers, gives us the right to expect the maximum achievable stability in work under any use cases (here, relative lightness is also beneficial CRI-O compared with Docker due to deliberate limitation of functionality).

When installing Kubernetes The “right way” way (according to the OCI, of course) using CRI-O on the CentOS 8 we ran into small difficulties, which, however, were successfully overcome. I will be glad to share with you the installation and configuration instructions, which together will take at most 10 minutes.

How to deploy Kubernetes on CentOS 8 using CRI-O

Prerequisites: At least one host (2 cores, 4 GB RAM, at least 15 GB storage) with CentOS 8 (Recommended installation profile “Server”), as well as entries for it in the local DNS (as a last resort, you can get by with an entry in / etc / hosts). And don’t forget disable swap

We perform all operations on the host as the root user, be careful.

  1. In the first step, we will configure the OS, install and configure the preliminary dependencies for CRI-O.
    • Let’s update the OS:
      dnf -y update

    • Next, you need to configure the firewall and SELinux. Here everything depends on the environment in which our host or hosts will work. You can either configure the firewall according to the recommendations from documentation, or if you are on a trusted network or use a third-party firewall, change the default zone to trusted or disable the firewall:
      firewall-cmd --set-default-zone trusted
      firewall-cmd --reload

      To turn off the firewall, you can use the following command:

      systemctl disable --now firewalld

      SELinux must be turned off or put into “permissive” mode:

      setenforce 0
      sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

    • load the necessary kernel modules and packages, configure the automatic loading of the br_netfilter module at system startup:
      modprobe overlay
      modprobe br_netfilter
      echo "br_netfilter" >> /etc/modules-load.d/br_netfilter.conf
      dnf -y install iproute-tc

    • to activate packet forwarding and correct traffic processing, we will make the appropriate settings:
      cat > /etc/sysctl.d/99-kubernetes-cri.conf <

      apply the settings made:

      sysctl --system

    • set the required version CRI-O (major version CRI-Oas already mentioned match the required version Kubernetes), since the latest stable version Kubernetes at the moment 1.18:
      export REQUIRED_VERSION=1.18

      add the necessary repositories:

      dnf -y install 'dnf-command(copr)'
      dnf -y copr enable rhcontainerbot/container-selinux
      curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo
      curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:$REQUIRED_VERSION.repo$REQUIRED_VERSION/CentOS_8/devel:kubic:libcontainers:stable:cri-o:$REQUIRED_VERSION.repo

    • now we can set CRI-O:
      dnf -y install cri-o

      Pay attention to the first nuance that we meet during the installation process: you need to edit the configuration CRI-O before starting the service, since the required conmon component has a different location from the specified one:

      sed -i 's//usr/libexec/crio/conmon//usr/bin/conmon/' /etc/crio/crio.conf

      Now you can activate and start the daemon CRI-O:

      systemctl enable --now crio

      You can check the status of the daemon:

      systemctl status crio

  2. Installation and activation Kubernetes...
    • Add the required repository:
      cat < /etc/yum.repos.d/kubernetes.repo
      exclude=kubelet kubeadm kubectl

      We can now install Kubernetes (version 1.18 as mentioned above):

      dnf install -y kubelet-1.18* kubeadm-1.18* kubectl-1.18* --disableexcludes=kubernetes

    • The second important nuance: since we do not use a demon Docker, but we use a demon CRI-O, before starting and initializing Kubernetes you need to make the appropriate settings in the configuration file /var/lib/kubelet/config.yaml, after creating the required directory:
      mkdir /var/lib/kubelet
      cat < /var/lib/kubelet/config.yaml
      kind: KubeletConfiguration
      cgroupDriver: systemd

    • The third important point that we encounter during the installation: despite the fact that we indicated the driver used cgroup, and setting it up through the arguments passed kubelet is deprecated (which is directly indicated in the documentation), we need to add arguments to the file, otherwise our cluster is not initialized:
      cat /dev/null > /etc/sysconfig/kubelet
      cat < /etc/sysconfig/kubelet
      KUBELET_EXTRA_ARGS=--container-runtime=remote --cgroup-driver=systemd --container-runtime-endpoint="unix:///var/run/crio/crio.sock"

    • Now we can activate the demon kubelet:
      sudo systemctl enable --now kubelet

      To customize control-plane or worker nodes in minutes, you can use with this script...

  3. It's time to initialize our cluster.
    • To initialize the cluster, run the command:
      kubeadm init --pod-network-cidr=

      Be sure to write down the command to join the cluster "kubeadm join ...", which is suggested to use at the end of the output, or at least the specified tokens.

    • Install the plugin (CNI) for the Pod network. I recommend using Calico... Perhaps more popular Flannel has compatibility issues with nftablesand yes Calico - the only CNI implementation recommended and fully tested by the project Kubernetes:
      kubectl --kubeconfig /etc/kubernetes/admin.conf apply -f 

    • To connect a worker node to our cluster, you need to configure it according to steps 1 and 2, or use script, then execute the command from the "kubeadm init ..." output that we wrote in the previous step:
      kubeadm join $CONTROL_PLANE_ADDRESS:6443 --token $TOKEN 
          --discovery-token-ca-cert-hash $TOKEN_HASH

    • Let's check that our cluster is initialized and started working:
      kubectl --kubeconfig=/etc/kubernetes/admin.conf get pods -A

    Done! You can already host the payload on your K8s cluster.

What lies ahead

Hope the instructions above helped save you some time and hassle.
The outcome of the processes taking place in the industry often depends on how they are accepted by the majority of end users and developers of other software in the corresponding niche. It is not yet clear where the OCI's initiatives will lead in a few years, but we will be happy to follow. You can share your opinion right now in the comments.

Stay tuned!

This article comes from the following sources:

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *