Onur Yasarlar
Search
K

Installing Container Runtime Interface

Getting Started

You can select one of the supported container runtime interfaces for your Kubernetes cluster infrastructure. Since Kubernetes is deprecating Docker as a container runtime after v1.20, I choose containerd as my runtime interface and writing an Ansible role to install it. Let's do deep dive on how to install containerd. You can find my Ansible role here.
All installation steps for different container runtimes can be found here.

Installing Prerequisites

containerd expects some kernel parameters and kernel modules to be set persistently. I am handling that step in a separate playbook as below:
---
- name: Enable kernel module
lineinfile:
path: /etc/modules-load.d/containerd.conf
line: "{{ item }}"
state: present
create: true
mode: '0644'
loop:
- overlay
- br_netfilter
- name: Reload kernel modules
modprobe:
name: "{{ item }}"
state: present
loop:
- overlay
- br_netfilter
- name: Setup required sysctl params
sysctl:
name: "{{ item.name }}"
value: "{{ item.value }}"
sysctl_file: /etc/sysctl.d/99-kubernetes-cri.conf
reload: true
loop:
- { name: net.bridge.bridge-nf-call-iptables, value: 1 }
- { name: net.ipv4.ip_forward, value: 1}
- { name: net.bridge.bridge-nf-call-ip6tables, value: 1}

Installing containerd runtime interface

I am covering containerd installation on Centos 7, Ubuntu 18.04, and Ubuntu 20.04. Each operating system has its own installation requirements. I prefer to split them into different plays and include them in my tasks/main.yml as below:
- name: Install containerd
include_tasks: "install_{{ ansible_distribution | lower }}.yaml"
So each supported operating system calls its own yaml file as below:
CENTOS 7
Ubuntu 18.04 / 20.04
tasks/install_centos.yaml
---
- name: Install on CentOS 7
block:
- name: Install required packages
package:
name:
- yum-utils
- device-mapper-persistent-data
- lvm2
state: present
- name: Create docker-ce package repository
get_url:
url: "https://download.docker.com/linux/centos/docker-ce.repo"
dest: /etc/yum.repos.d/docker-ce.repo
owner: root
group: root
mode: '0644'
- name: Install containerd.io
package:
name: containerd.io
state: present
when: ansible_distribution_major_version | int == 7
tasks/install_ubuntu.yaml
---
- name: Install containerd on Ubuntu 18.04 / 20.04
apt:
name: containerd
update_cache: yes
when: (ansible_distribution_version.split(".") | join == "1804") or
(ansible_distribution_version.split(".") | join == "2004")
containerd version is not defined in the current version of the Ansible role. In the near future, I can add it to provide more stability but for now, I will go with the latest version always.

Configuration

Once the binary is installed, we need to create the configuration file under /etc/containerd/config.toml. Then we will need to enable and restart the service so the new configuration can be read by the daemon. Since the configuration step is common on all operating systems, I created a single play and include it in the main play. Let's take a look at the configuration code:
tasks/configure.yaml
---
- name: Create /etc/containerd
file:
path: /etc/containerd
state: directory
mode: '0755'
- name: Check if /etc/containerd/config.toml exists
stat:
path: /etc/containerd/config.toml
register: containerd_config
- name: Copy containerd configuration
shell: "containerd config default > /etc/containerd/config.toml"
args:
warn: no
tags: ['skip_ansible_lint']
when: not containerd_config.stat.exists
notify: restart containerd
- name: Enable containerd
service:
name: containerd
enabled: true

Putting things together

All the above steps are included in the main playbook of the role as below:
tasks/main.yml
- name: Handle prereqs
include_tasks: prereq.yaml
- name: Install containerd
include_tasks: "install_{{ ansible_distribution | lower }}.yaml"
- name: Configure containerd
include_tasks: configure.yaml
Calling this role will enable us to install containerd on supported operating systems. Now we can continue with installing kubeadm, kubelet, and kubectl.