CRI-O як заміна Docker як виконуване середовище для Kubernetes: налаштування на CentOS 8

Вітання! Мене звуть Сергій, я DevOps у Surf. DevOps-відділ у Surf ставить своїм завданням не лише налагодження взаємодії між фахівцями та інтеграцію робочих процесів, а й активні дослідження та впровадження актуальних технологій як у власну інфраструктуру, так і в інфраструктуру замовника.

Нижче я розповім про зміни в технологічному стеку для контейнерів, з якими ми зустрілися при вивченні дистрибутива 8 CentOS і про те, що таке CRI-O і як швидко налаштувати з його допомогою виконуване середовище для Кубернетес.

CRI-O як заміна Docker як виконуване середовище для Kubernetes: налаштування на CentOS 8

Чому Docker відсутня у стандартній поставці CentOS 8

Після встановлення останніх великих релізів RHEL 8 або 8 CentOS не можна не помітити: у цих дистрибутивах та офіційних репозиторіях відсутній додаток Docker, яке ідеологічно та функціонально замінюють собою пакети Подман, Buildah (присутні в дистрибутиві за замовчуванням) та CRI-O. Це пов'язано з практичною реалізацією стандартів, що розробляються, зокрема, і компанією Red Hat у рамках проекту Open Container Initiative (OCI).

Мета OCI, що є частиною The Linux Foundation, — створення відкритих індустріальних стандартів для форматів та середовища контейнерів, які б вирішували відразу кілька завдань. По-перше, не суперечили як філософії Linux (наприклад, у тій її частині, що кожна програма повинна виконувати якусь одну дію, а Docker являє собою такий собі комбайн все-в-одному). По-друге, могли б усунути всі недоліки в програмному забезпеченні Docker. По-третє, були б повністю сумісними з бізнесовими вимогами, що висуваються провідними комерційними платформами для розгортання, управління та обслуговування контейнеризованих додатків (наприклад, Red Hat OpenShift).

Недоліки Docker і переваги нового ПЗ вже були досить докладно описані в цієї статті, а з докладним описом як всього пропонованого в рамках проекту OCI стека ПЗ та його архітектурними особливостями можна ознайомитись в офіційній документації та статтях як від самої Red Hat (непогана стаття в Red Hat blog), так і в сторонніх оглядах.

Важливо відзначити, яку функціональність мають компоненти пропонованого стеку:

  • Подман - Безпосередня взаємодія з контейнерами та сховищем образів через процес runC;
  • Buildah - Складання та завантаження в реєстр образів;
  • CRI-O - Виконуване середовище для систем оркестрації контейнерів (наприклад, Kubernetes).

Думаю, що для розуміння загальної схеми взаємодії між компонентами стека доцільно навести тут схему зв'язків Кубернетес c runC та низькорівневими бібліотеками з використанням CRI-O:

CRI-O як заміна Docker як виконуване середовище для Kubernetes: налаштування на CentOS 8

CRI-O и Кубернетес дотримуються одного і того ж циклу випуску та підтримки (матриця сумісності дуже проста: мажорні версії Кубернетес и CRI-O збігаються), а це, з урахуванням орієнтиру на повне та всебічне тестування роботи даного стека розробниками, дає нам право очікувати максимально досяжної стабільності в роботі за будь-яких сценаріїв використання (тут на користь йде і відносна легковажність CRI-O порівняно з Docker з цілеспрямованого обмеження функціональності).

При встановленні Кубернетес "right way" способом (на думку OCI, звичайно) з використанням CRI-O на 8 CentOS ми зіткнулися з невеликими труднощами, які, однак, успішно подолали. Буду радий поділитися з вами інструкцією з встановлення та налаштування, які разом займуть від сили 10 хвилин.

Як розгорнути Kubernetes на CentOS 8 з використанням середовища CRI-O

Попередні умови: наявність як мінімум одного хоста (2 cores, 4 GB RAM, накопичувач не менше 15 GB) із встановленою 8 CentOS (рекомендується профіль установки «Server»), а також записи для нього в локальному DNS (у крайньому випадку можна обійтися записом /etc/hosts). І не забудьте вимкнути swap.

Всі операції на хості виконуємо від імені користувача root, будьте уважні.

  1. На першому кроці налаштуємо ОС, встановимо та налаштуємо попередні залежності для CRI-O.
    • Обновимо ОС:
      dnf -y update
      

    • Далі потрібно налаштувати файрвол і SELinux. Тут у нас все залежить від оточення, в якому працюватимуть наш хост чи хости. Ви можете або налаштувати файрволл за рекомендаціями з документації, або, якщо ви перебуваєте в довіреній мережі або застосовуєте сторонній файрволл, змінити зону за замовчуванням на довірену або вимкнути файрволл:
      firewall-cmd --set-default-zone trusted
      
      firewall-cmd --reload

      Щоб вимкнути файрвол можна використовувати наступну команду:

      systemctl disable --now firewalld
      

      SELinux потрібно вимкнути або перевести в режим "permissive":

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

    • завантажимо необхідні модулі ядра та пакети, налаштуємо автоматичне завантаження модуля «br_netfilter» при старті системи:
      modprobe overlay
      
      modprobe br_netfilter
      
      echo "br_netfilter" >> /etc/modules-load.d/br_netfilter.conf
      
      dnf -y install iproute-tc
      

    • для активації форвардингу пакетів та коректної обробки трафіку зробимо відповідні налаштування:
      cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
      net.bridge.bridge-nf-call-iptables = 1
      net.ipv4.ip_forward = 1
      net.bridge.bridge-nf-call-ip6tables = 1
      EOF
      

      застосуємо зроблені налаштування:

      sysctl --system

    • поставимо необхідну версію CRI-O (мажорна версія CRI-O, як згадувалося, збігаються з необхідної версією Кубернетес), оскільки остання стабільна версія Кубернетес на даний момент 1.18:
      export REQUIRED_VERSION=1.18
      

      додамо необхідні репозиторії:

      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 https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_8/devel:kubic:libcontainers:stable.repo
      
      curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:$REQUIRED_VERSION.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$REQUIRED_VERSION/CentOS_8/devel:kubic:libcontainers:stable:cri-o:$REQUIRED_VERSION.repo

    • тепер ми можемо встановити CRI-O:
      dnf -y install cri-o
      

      Зверніть увагу на перший аспект, який ми зустрічаємо в процесі інсталяції: потрібно відредагувати конфігурацію CRI-O перед запуском сервісу, оскільки необхідний компонент conmon має відмінне від зазначеного розташування:

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

      Тепер можна активувати та запустити демон CRI-O:

      systemctl enable --now crio
      

      Можна перевірити статус демона:

      systemctl status crio
      

  2. Встановлення та активація Кубернетес.
    • Додамо необхідний репозиторій:
      cat <<EOF > /etc/yum.repos.d/kubernetes.repo
      [kubernetes]
      name=Kubernetes
      baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch
      enabled=1
      gpgcheck=1
      repo_gpgcheck=1
      gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
      exclude=kubelet kubeadm kubectl
      EOF
      

      Тепер ми можемо встановити Кубернетес (версії 1.18, як зазначалося вище):

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

    • Другий важливий нюанс: оскільки ми не використовуємо демон Docker, а використовуємо демон CRI-O, до запуску та ініціалізації Кубернетес потрібно внести відповідні налаштування до конфігураційного файлу /var/lib/kubelet/config.yaml, попередньо створивши потрібний каталог:
      mkdir /var/lib/kubelet
      
      cat <<EOF > /var/lib/kubelet/config.yaml
      apiVersion: kubelet.config.k8s.io/v1beta1
      kind: KubeletConfiguration
      cgroupDriver: systemd
      EOF

    • Третій важливий момент, з яким ми стикаємося при встановленні: незважаючи на те, що ми вказали драйвер, що використовується cgroup, та його налаштування через аргументи передані кубелет застаріла (на що прямо вказано в документації), нам необхідно додати до файлу аргументи, інакше наш кластер не ініціалізується:
      cat /dev/null > /etc/sysconfig/kubelet
      
      cat <<EOF > /etc/sysconfig/kubelet
      KUBELET_EXTRA_ARGS=--container-runtime=remote --cgroup-driver=systemd --container-runtime-endpoint='unix:///var/run/crio/crio.sock'
      EOF

    • Тепер ми можемо активувати демон кубелет:
      sudo systemctl enable --now kubelet
      

      щоб налаштувати контрольна площина або робочий ноди за лічені хвилини, ви можете скористатися цим скриптом.

  3. Час ініціалізувати наш кластер.
    • Для ініціалізації кластера виконайте команду:
      kubeadm init --pod-network-cidr=10.244.0.0/16
      

      Обов'язково запишіть команду приєднання до кластера «kubeadm join …», якою пропонується скористатися в кінці виводу, або, як мінімум, вказані токени.

    • Встановимо плагін (CNI) для роботи Pod network. Я рекомендую використовувати коленкор. Можливо, популярніший Фланель має проблеми із сумісністю з nftables, так і так коленкор — єдина реалізація CNI, рекомендована та повністю протестована проектом Кубернетес:
      kubectl --kubeconfig /etc/kubernetes/admin.conf apply -f https://docs.projectcalico.org/v3.15/manifests/calico.yaml 

    • Для підключення worker ноди до нашого кластера її потрібно налаштувати за пунктами інструкції 1 та 2, або скористатися скриптом, потім виконати команду з виводу "kubeadm init ...", яку ми записали на попередньому етапі:
      kubeadm join $CONTROL_PLANE_ADDRESS:6443 --token $TOKEN 
          --discovery-token-ca-cert-hash $TOKEN_HASH

    • Перевіримо, що наш кластер ініціалізований і розпочав роботу:
      kubectl --kubeconfig=/etc/kubernetes/admin.conf get pods -A
      

    Готово! Ви вже можете розміщувати на вашому кластері K8s корисне навантаження.

Що нас чекає попереду

Сподіваюся, що інструкція вище допомогла заощадити вам трохи часу та нервів.
Результат процесів, що відбуваються в індустрії, часто залежить від того, як їх приймає основна маса кінцевих користувачів та розробників іншого програмного забезпечення у відповідній ніші. Поки що не зовсім зрозуміло, до якого підсумку за кілька років приведуть ініціативи OCI, але ми із задоволенням за цим слідкуватимемо. Своєю думкою ви можете поділитись прямо зараз у коментарях.

Залишайтеся з нами!

Ця стаття з'явилася завдяки наступним джерелам:



Джерело: habr.com

Додати коментар або відгук