Концепции доставки кода в Kubernetes

Концепции доставки кода в Kubernetes


Оглавление

Дисклеймер: Данная статья не несёт в себе практических описаний того, как реализовать выкладку вашего приложения в Kubernetes. Какую конечную версию решения и какие инструменты будете использовать — решать только вам.

Контейнеризированные приложения продолжают захватывать мир. Та революция, которую начал Docker, будет приобретать всё большие масштабы. После Docker к нам в 2014 году, а если брать версию 1.0 — в 2015, пришёл Kubernetes, и, давайте скажем честно, он классный. Он позволяет решать кучу задач в автоматическом режиме, из-за которых вы, скорее всего, как OPS-инженер могли плохо спать по ночам. Kubernetes принёс нам новый уровень абстракций над контейнеризированными приложениями. И сейчас большинство компаний стремятся перетащить в него свою рабочую нагрузку и управлять через него своими приложениями. А там, где есть приложения, нам надо продумать, как мы будем их выкатывать. Об этом сегодня и поговорим.

Модели доставки кода в кластер

И вот тут я должен сделать первое и главное для нас уточняющее разъяснение. На мой взгляд, существует две модели доставки кода в кластер — условные Pull и Push. В модели Pull мы передаём новое желаемое состояние кластера путём применения манифестов через kubectl, Helm, Kustomize или любым другим методом. В модели Push реализован подход GitOps.

В кластере Kubernetes есть механизм, который следит за Git-репозиторием, и в случае изменения в нём кода, этот механизм приводит кластер в состояние, чётко описанное этим кодом. Почему это хорошо? Потому что у вас есть один источник правды — SST (Single Source of Truth). Допустим, ручное изменение количества ReplicaSet c двух до трёх не будет сохранено на долгое время, так как механизм согласования вернёт кластер в состояние, описанное в Git-репозитории.

Деплой манифестов. Модель Pull

Взглянем на изображение ниже.

CI CD в Kubernetes.jpg
На скрине схематично показан процесс выката приложения

Разработчик пушит изменения в Git-репозиторий, в данном случае это GitLab, но может быть Bitbucket или GitHub, это неважно. В этом репозитории также хранится ваше описание Kubernetes, это могут быть Helm-чарты или просто манифесты YAML — решать вам в зависимости от ваших предпочтений. Вы можете хранить файлы описания в отдельном репозитории. Но тогда в случае, например, с GitLab, нужно будет воспользоваться хуками для активации выкладки с изменёнными параметрами после сборки образа.

Продолжим. Изменения в коде триггерят активацию пайплайна сборки. Как вы будете собирать изменения тоже неважно — Jenkins, GitLab CI/CD или любой другой механизм. Главное — понять концепцию. Активация пайплайна заставляет сборщик собрать новый образ приложения и опубликовать его в реестре контейнеров. Используйте теги или переменные окружения для версионирования образов.

Далее наш собранный образ проходит автоматические тесты. Затем мы разворачиваем наш релиз — в примере с помощью Helm — в наш кластер Kubernetes. Не забываем про встроенную возможность сделать rollback. В общем, так выглядит стандартная схема деплоя приложения в кластер. Обязательно продумайте, как у вас будет выполняться миграция, как эффективно убрать даунтайм приложения или то, как и куда будут попадать пользователи во время деплоя.

GitOps подход. Модель Push

Давайте взглянем на схему реализации push-модели.

Доставка кода в Kubernetes.jpg

Данный подход предполагает использование двух репозиториев. В первом репозитории мы храним код нашего приложения. Там же мы храним Docker-файлы для сборки, но не храним Helm-чарты или описания желаемого состояния кластера в простых манифестах или с применением kustomize. Триггер сборки активирует пайплайн, который собирает и тестирует новый образ приложения, а также пушит его в registry.

Затем вносятся изменения в репозиторий с манифестами, которые описывают желаемое состояние кластера. Далее оператор синхронизации — в данном случае представлен Argo CD, однако вы можете использовать Flux2 — определяет, что текущее состояние не соответствует описанному состоянию в репозитории, и приводит кластер к этому состоянию. Оператор синхронизации является приложением, предварительно задеплоенным в кластер. Хранение манифестов в отдельном репозитории с их синхронизацией упрощает ваш CI-пайплайн, избавляя его от задач выката приложения.

Сегодня мы рассмотрели две основные модели CI/CD-доставки кода в кластер Kubernetes. Надеюсь, после этой статьи стало немного понятнее, как реализовать выкладку вашего приложения. По какой модели лучше работать — решать вам. Всё будет зависеть от тех задач, которые выполняет приложение, и от того, из каких компонентов оно состоит. Важно использовать Kubernetes с умом и не забывать, что мы используем инструменты для достижения цели, а не ставим цели, чтобы для них подходили конкретные инструменты.

Читайте также нашу прошлую статью «Пошаговая настройка Kube-Prometheus-Stack для мониторинга Kubernetes»