Onur Yasarlar
  • About Me
  • Linux
    • How to Install KVM on CentOS 7/8 and Ubuntu 18/20
    • How to Install VirtualBox on CentOS 7/8 and Ubuntu 18
    • How to Install Vagrant on Centos 7/8 and Ubuntu 18
    • Using vim Effectively
  • Kubernetes
    • How to Install a Kubernetes Cluster
      • Installing Prerequisites for Kubernetes Cluster Installation
      • Installing Container Runtime Interface
      • Installing kubeadm
    • How to Install and Use K3D
  • CI/CD
    • GitLab CICD Pipeline Concepts
      • Stages
    • Quick Introduction to GitLab CICD Pipelines
    • How to install custom Gitlab runners with libvirt executor
  • Azure
    • Azure Infrastructure Automation with Gitlab CI
  • TERRAFORM
    • How to create a Terraform Module
Powered by GitBook
On this page
  • Getting Started
  • Installing Prerequisites
  • Installing containerd runtime interface
  • Configuration
  • Putting things together

Was this helpful?

  1. Kubernetes
  2. How to Install a Kubernetes Cluster

Installing Container Runtime Interface

PreviousInstalling Prerequisites for Kubernetes Cluster InstallationNextInstalling kubeadm

Last updated 4 years ago

Was this helpful?

Getting Started

You can select one of the supported container runtime interfaces for your Kubernetes cluster infrastructure. Since Kubernetes is 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 .

All installation steps for different container runtimes can be found .

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:

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.

deprecating Docker
here
here