Привет! Меня зовут Сергей, я DevOps в Surf. DevOps-отдел в Surf ставит своей задачей не только налаживание взаимодействия между специалистами и интеграцию рабочих процессов, но и активные исследования и внедрение актуальных технологий как в собственную инфраструктуру, так и в инфраструктуру заказчика.
Ниже я немного расскажу об изменениях в технологическом стеке для контейнеров, с которыми мы встретились при изучении дистрибутива CentOS 8 и о том, что такое CRI-O и как быстро настроить с его помощью исполняемую среду для Kubernetes.
После установки последних крупных релизов RHEL 8 или CentOS 8 нельзя не заметить: в этих дистрибутивах и официальных репозиториях отсутствует приложение Docker, которое идеологически и функционально заменяют собой пакеты Podman, 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), так и в сторонних обзорах.
Важно отметить, какую функциональность имеют компоненты предлагаемого стека:
Думаю, что для понимания общей схемы взаимодействия между компонентами стека целесообразно привести здесь схему связей Kubernetes c runC и низкоуровневыми библиотеками с использованием CRI-O:
CRI-O и Kubernetes придерживаются одного и того же цикла выпуска и поддержки (матрица совместимости очень проста: мажорные версии Kubernetes и CRI-O совпадают), а это, с учётом ориентира на полное и всестороннее тестирование работы данного стека разработчиками, даёт нам право ожидать максимально достижимой стабильности в работе при любых сценариях использования (здесь на пользу идет и относительная легковесность CRI-O по сравнению с Docker в силу целенаправленного ограничения функциональности).
При установке Kubernetes «right way» способом (по мнению OCI, конечно) с использованием CRI-O на CentOS 8 мы столкнулись с небольшими затруднениями, которые, однако, успешно преодолели. Буду рад поделиться с вами инструкцией по установке и настройке, которые в совокупности займут от силы 10 минут.
Предварительные условия: наличие как минимум одного хоста (2 cores, 4 GB RAM, накопитель не менее 15 GB) с установленной CentOS 8 (рекомендуется профиль установки «Server»), а также записи для него в локальном DNS (в крайнем случае можно обойтись записью в /etc/hosts). И не забудьте отключить swap.
Все операции на хосте производим от имени пользователя root, будьте внимательны.
Надеюсь, что инструкция выше помогла сэкономить вам немного времени и нервов.
Исход процессов, происходящих в индустрии, зачастую зависит от того, как их принимает основная масса конечных пользователей и разработчиков другого ПО в соответствующей нише. Пока не совсем ясно, к какому итогу через несколько лет приведут инициативы OCI, но мы будем с удовольствием за этим следить. Своим мнением вы можете поделиться прямо сейчас в комментариях.
Stay tuned!
Данная статья появилась благодаря следующим источникам:
Ниже я немного расскажу об изменениях в технологическом стеке для контейнеров, с которыми мы встретились при изучении дистрибутива CentOS 8 и о том, что такое CRI-O и как быстро настроить с его помощью исполняемую среду для Kubernetes.
Почему Docker отсутствует в стандартной поставке CentOS 8
После установки последних крупных релизов RHEL 8 или CentOS 8 нельзя не заметить: в этих дистрибутивах и официальных репозиториях отсутствует приложение Docker, которое идеологически и функционально заменяют собой пакеты Podman, 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), так и в сторонних обзорах.
Важно отметить, какую функциональность имеют компоненты предлагаемого стека:
- Podman — непосредственное взаимодействие с контейнерами и хранилищем образов через процесс runC;
- Buildah — сборка и загрузка в реестр образов;
- CRI-O — исполняемая среда для систем оркестрации контейнеров (например, Kubernetes).
Думаю, что для понимания общей схемы взаимодействия между компонентами стека целесообразно привести здесь схему связей Kubernetes c runC и низкоуровневыми библиотеками с использованием CRI-O:
CRI-O и Kubernetes придерживаются одного и того же цикла выпуска и поддержки (матрица совместимости очень проста: мажорные версии Kubernetes и CRI-O совпадают), а это, с учётом ориентира на полное и всестороннее тестирование работы данного стека разработчиками, даёт нам право ожидать максимально достижимой стабильности в работе при любых сценариях использования (здесь на пользу идет и относительная легковесность CRI-O по сравнению с Docker в силу целенаправленного ограничения функциональности).
При установке Kubernetes «right way» способом (по мнению OCI, конечно) с использованием CRI-O на CentOS 8 мы столкнулись с небольшими затруднениями, которые, однако, успешно преодолели. Буду рад поделиться с вами инструкцией по установке и настройке, которые в совокупности займут от силы 10 минут.
Как развернуть Kubernetes на CentOS 8 с использованием среды CRI-O
Предварительные условия: наличие как минимум одного хоста (2 cores, 4 GB RAM, накопитель не менее 15 GB) с установленной CentOS 8 (рекомендуется профиль установки «Server»), а также записи для него в локальном DNS (в крайнем случае можно обойтись записью в /etc/hosts). И не забудьте отключить swap.
Все операции на хосте производим от имени пользователя root, будьте внимательны.
- На первом шаге настроим ОС, установим и настроим предварительные зависимости для 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, как уже упоминалось, совпадают с требуемой версией Kubernetes), так как последняя стабильная версия Kubernetes на данный момент 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
- Обновим ОС:
- Установка и активация Kubernetes.
- Добавим требуемый репозиторий:
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
Теперь мы можем установить Kubernetes (версии 1.18, как уже указывалось выше):
dnf install -y kubelet-1.18* kubeadm-1.18* kubectl-1.18* --disableexcludes=kubernetes
- Второй важный нюанс: так как мы не используем демон Docker, а используем демон CRI-O, до запуска и инициализации Kubernetes требуется внести соответствующие настройки в конфигурационный файл /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, и его настройка через аргументы передаваемые kubelet устарела (на что прямо указано в документации), нам необходимо добавить в файл аргументы, иначе наш кластер не инициализируется:
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
- Теперь мы можем активировать демон kubelet:
sudo systemctl enable --now kubelet
Чтобы настроить control-plane или worker ноды за считанные минуты, вы можете воспользоваться этим скриптом.
- Добавим требуемый репозиторий:
- Пора инициализировать наш кластер.
- Для инициализации кластера выполните команду:
kubeadm init --pod-network-cidr=10.244.0.0/16
Обязательно запишите команду присоединения к кластеру «kubeadm join ...», которой предлагается воспользоваться в конце вывода, либо, как минимум, указанные токены.
- Установим плагин (CNI) для работы Pod network. Я рекомендую использовать Calico. Возможно, более популярный Flannel имеет проблемы с совместимостью с nftables, да и Calico — единственная реализация CNI, рекомендуемая и полностью протестированная проектом Kubernetes:
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, но мы будем с удовольствием за этим следить. Своим мнением вы можете поделиться прямо сейчас в комментариях.
Stay tuned!
Данная статья появилась благодаря следующим источникам:
- Раздел о Container runtimes в документации Kubernetes
- Странице проекта CRI-O в сети Internet
- Статьям в блогах Red Hat: вот этой, этой и многим другим
JuriM
Одним из недостатков докера является единая точка отказа в случае падения докер сервиса. На схеме у вас указан cri-o daemon, что произойдет если этот сервис упадет?
creker
Тоже самое что и с докером? Как еще куберу запускать контейнеры и следить за их состоянием, если упал демон, через который, собственно, это и делается? Упадет CRI демон — нода считай отказала. Докер сам по себе тут не при чем. Не особо это кстати и единая точка отказа для кубера. Поды должны просто переехать на другую ноду. Разве что если на отказавшей ноде контейнеры удерживают какие-то вольюмы.
Единственный клюс CRI-O, о котором всегда и говорят, это потенциально меньшая вероятность собственно падения, т.к. сам демон намного проще. Но это так, теория. На моей практике докер демон никогда не падал хоть при каких нагрузках, когда даже ядро задыхается ворочать сотни подов.
VolCh
Можно будет продолжать билдить образы и пушиьь их в регистр :)
grayhunter Автор
Добрый день! По сравнению в реализацией Docker демона, CRI-O, по официальной информации, проходит намного более тщательное тестирование комплексной работы с Kubernetes в тесной интеграции команд разработчиков, поэтому вероятность существования багов и последующего отказа в целом меньше, однако сложно сказать насколько именно. С точки зрения наличия точек отказа, по сути их количество не изменилось, однако это решается кластеризацией Kubernetes. Вопросы кластеризации мы не затрагивали в этой статье, она скорее предназначена для быстрого старта на базе CRI-O для знакомства со связкой.