- PVSM.RU - https://www.pvsm.ru -

Привет! Меня зовут Егор Салиев, я DevOps-инженер в провайдере IT-решений Hilbert Team. Сегодня хочу затронуть тему, которую недавно обсуждали на Kuber MeetUp в Selectel, и которая будет интересна инженерам, занимающимся настройкой CI/CD и деплоем. Рассмотрим, как со временем менялась практика развертывания приложений в Kubernetes. Обсудим переход от ручного процесса к автоматизации и сравним две модели деплоя: push и pull.
В результате мы дойдем до современного подхода — GitOps с Argo CD. Такой метод помогает компаниям стандартизировать процессы, уменьшить количество ошибок и сбоев, ускорить вывод продукта на рынок, а также сократить расходы на инфраструктуру.
Статья создана по мотивам доклада от Hilbert Team [1], представленного на Selectel Kuber MeetUp.
Используйте оглавление, если не хотите читать текст полностью:
→ GitLab и Push‑модель [2]
→ Kubectl [3]
→ Kustomize [4]
→ Helm [5]
→ Helmfile [6]
→ Сравнение [7]
→ Pull-модель, GitOps и Argo CD [8]
→ Предпосылки к использованию нового подхода [9]
→ Argo CD [10]
→ Унификация деплоя [11]
→ Заключение [12]
Итак, у нас есть Gitlab, но пока нет GitOps. Это означает, что хотя мы используем Git для управления версиями кода, у нас еще не внедрена система, в которой все изменения в конфигурации инфраструктурой осуществляются через коммиты в репозиторий. Кроме того, потребуется продумать и настроить конвейер CI/CD, который возьмет на себя автоматизацию процессов сборки, тестирования и развертывания.
Доставка приложения в Kubernetes (K8s) — и есть наша текущая основная задача. Существует несколько различных стратегий деплоя в K8s, каждая из которых имеет свои преимущества, недостатки, а также набор используемых инструментов.

В push‑модели сборка, тестирование и развертывание приложения в кластер происходит после каждого выполнения команды git push. То есть разработчик, отправляя свой код в репозиторий, запускает цепочку действий, в результате которой обновленное приложение становится доступным для пользователей. Для этого GitLab предлагает несколько встроенных инструментов.

Как работает метод Push в GitLab.
Когда разработчик вносит изменения в своей ветке кода или создает Merge Request (MR) в основной (main), это действие активирует триггер. Запускается заранее определенный пайплайн — последовательность автоматизированных процессов, которые обеспечивают сборку, тестирование и развертывание нового кода.
При этом выполняются различные build-процессы, которые обычно создают образы с помощью Docker или Kaniko. Может контролироваться как корректность работы нового кода, так и его совместимость с существующей системой.
После успешного прохождения всех этапов, новый образ приложения отправляется в реестр, который служит хранилищем для готовых к развертыванию артефактов. Деплой — заключительный этап, который представляет собой процесс размещения нового образа приложения на целевом окружении, таком как production, staging или development.
Рассмотрим некоторые из существующих инструментов деплоя:
Kubectl — это стандартный и основной инструмент для развертывания приложений в Kubernetes. Кроме того, с его помощью можно выполнять разнообразные операции, такие как масштабирование, обновление, мониторинг и отладка. Для этого необходимо подготовить набор манифестов, которые описывают желаемое состояние приложения в кластере и стандартные сущности K8s: Deployment, Pod, Service, Ingress, ConfigMap, Secret и другие.
Deployment отвечает за развертывание и управление репликами. Pod представляет собой экземпляр запущенного приложения, Service обеспечивает сетевой доступ, Ingress управляет внешним трафиком, ConfigMap и Secret хранят конфигурацию и секретные данные.
Ниже пример, где в корневом каталоге проекта создается файл .gitlab-ci.yml, который определяет этапы пайплайна CI/CD. В нем описываются задания, которые необходимо выполнить — например, сборка образа Docker, тестирование и развертывание в Kubernetes:
deploy-kubectl:
stage: deploy
image: dtzar/helm-kubectl:3.15
before_script:
- kubectl config use-context $GITLAB_AGENT
script:
- kubectl apply -f test-app/
rules:
- if: $CI_COMMIT_BRANCH
when: manual
Файл: .gitlab-ci.yml.
Команда kubectl apply применяет манифесты к кластеру — все сущности в нем приводятся к состоянию в соответствии с манифестами.

Модель деплоя Kubectl.
Преимущества
Недостатки
Kustomize — инструмент управления конфигурациями Kubernetes, который позволяет кастомизировать YAML-манифесты без необходимости использования шаблонов. Он работает, применяя набор патчей и трансформаций к базовому набору конфигураций, которые затем применяются с помощью kubectl.
Основные концепции Kustomize

Модель деплоя Kustomize.
В примере ниже есть папка base, где хранятся базовые конфигурации для всех сред, и папки overlays, которые содержат специфические настройки для dev, staging, prod и других сред:
deploy-kustomize:
stage: deploy
image: dtzar/helm-kubectl:3.15
before_script:
- kubectl config use-context $GITLAB_AGENT
- cd deploy/base
- kustomize edit set namespace $CI_ENVIRONMENT_NAME-test-app
- kustomize edit set image test-app=$CI_REGISTRY_IMAGE/test-app:$CI_COMMIT_SHORT_SHA
- kustomize build ../overlays/$CI_ENVIRONMENT_NAME >gt $CI_PROJECT_DIR/kustomized.yaml
script:
- kubectl create ns $CI_ENVIRONMENT_NAME-test-app || true
- kubectl apply -f $CI_PROJECT_DIR/kustomized.yaml
rules:
- if: $CI_COMMIT_BRANCH
when: manual
Файл: .gitlab-ci.yml
Для работы с ресурсами в Kustomize используется файл kustomization.yaml, в котором указывается, что именно должно быть изменено и каким образом.
Преимущества Kustomize
Однако у этого инструмента есть и недостатки: требуется время, чтобы исследовать его особенности и научиться эффективно использовать.
Selectel скоро выпустит комикс о путешествиях ИБ-специалиста! Регистрируйтесь [13], чтобы узнать о публикации первыми. Бонусом сможете выиграть один из 15 комплектов призов.
Helm — это менеджер пакетов для Kubernetes. Он использует концепцию чартов (charts), содержащих все необходимые ресурсы для развертывания приложения, такие как Deployment, Service, ConfigMap и другие. Helm использует шаблоны на языке Go для генерации манифестов Kubernetes на основе значений, предоставляемых пользователем. Чарты в Helm могут быть с вложенными сабчартами и храниться в любом реестре.
Деплой приложения в K8s с применением Helm-чарта выглядит действительно просто. При выполнении команды helm install Helm берет на себя создание всех необходимых ресурсов Kubernetes, таких как Deployment, Service и ConfigMap.

Модель деплоя Helm.
Код в примере ниже описывает задачу для развертывания Helm-чарта:
deploy-helm:
stage: deploy
image: dtzar/helm-kubectl:3.15
before_script:
- kubectl config use-context $GITLAB_AGENT
script:
- helm upgrade --install test-app ./chart
-f values.yaml
-n test-app --create-namespace
rules:
- if: $CI_COMMIT_BRANCH
when: manual
В итоге при коммите приложение test-app развернется и обновится, используя чарт из директории ./chart и файл значений _values.yaml.
Преимущества
Недостатки
Helmfile — дополнительный уровень абстракции над Helm для декларативного описания чартов. Его в чем‑то можно сравнить с Docker Compose. С помощью Helmfile можно легко управлять несколькими чартами и их зависимостями.

Модель деплоя helmfile.
В примере ниже задача синхронизирует релизы Helm, определенные в helmfile.yaml:
deploy-helmfile:
stage: deploy
image: $CI_REGISTRY/tools/helmfile
before_script:
- kubectl config use-context $GITLAB_AGENT
script:
- helmfile --namespace $ENVIRONMENT_NAMESPACE sync
rules:
- if: $CI_COMMIT_BRANCH
when: manual
Файл: .gitlab-ci.yml
Преимущества
Ниже сравнительная таблица по всем описанным инструментам:

Когда мы разворачиваем приложения в Kubernetes, используя push-модель, то конфигурация ресурсов хранится в etcd — встроенной в K8s базе данных. Такой подход имеет свои нюансы — возникает проблема конфигурационного дрейфа (configuration drifting):
Решить эту проблему можно с помощью GitOps и Argo CD.

Pull-модель.
Чаще всего под GitOps понимают именно Pull‑модель взаимодействия с Git. Так же, как и в Push‑модели, информация о кластере расположена в Git-репозитории. Отличие в том, что внесение изменений в кластер происходит не по срабатыванию триггера на команду git push. Напротив — внешний агент следит за изменениями в репозитории, постоянно сравнивает данные в нем с состоянием Kubernetes и при необходимости меняет конфигурацию. Агент чаще всего расположен в том же кластере, где происходит развертывание.
Использование такого подхода позволяет избежать некоторых проблем. Например, если пользователь напрямую внесет изменения в кластер, внешний агент увидит это и вернет кластер в состояние, прописанное в Git. Подобная строгость мотивирует пользователей вместо прямого воздействия на кластер делать правки в единственном допустимом источнике истины — в репозитории.
Argo CD — декларативный GitOps-ориентированный популярный инструмент непрерывной доставки для Kubernetes.
Читайте также статью «Что такое GitOps? Краткий обзор методологии и знакомство с ArgoCD [14]»
Основные компоненты Argo CD
Argo CD управляет не непосредственно манифестами и Helm-чартами, а Applications — абстракциями более высокого уровня, которые описывают желаемое состояние Kubernetes-ресурсов в Git-репозитории. Application может ссылаться на различные источники, такие как Helm-чарты, Kustomize-файлы, Jsonnet-манифесты или обычные Kubernetes-манифесты. Это позволяет выбирать подходящие инструменты для описания инфраструктуры, сохраняя единый механизм управления.
В примере ниже в локальном кластере создается приложение test-app и настраивается автоматическое отслеживание Git‑репозитория:
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: test-app namespace: Argo CD spec: source: path: test-app repoURL: https://gitlab.example.ru/gitops/prod-cluster.git targetRevision: HEAD destination: namespace: test-app server: https://kubernetes.default.svc project: prod
Если приложение одно, то его несложно создавать вручную. Другое дело, когда количество сервисов и, соответственно, приложений, увеличивается, такой подход становится неэффективным и трудоемким. Argo CD предлагает решение этой проблемы — ApplicationSet, который позволяет динамически создавать приложения по определенным правилам (generators).
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: tenants
namespace: Argo CD
spec:
generators:
- git:
repoURL: https://gitlab.example.ru/gitops/prod-cluster.git
revision: HEAD
directories:
- path: tenants/*
Манифест выше создает ApplicationSet, который автоматически генерирует несколько приложений на основе структуры каталогов в Git. В этом примере git generator следит за изменениями в репозитории. Если в tenants появится новый каталог с конфигурацией (Helm-чарт или манифест), то Argo CD автоматически развернет приложение.
Argo CD оперирует двумя основными сущностями: приложениями (Applications) и проектами (Projects). Они играют ключевую роль в управлении конфигурацией, так как могут быть организованы для работы в разных средах (например, dev, staging, prod) и кластерах. Важно: именно ими управляет Argo CD, а не манифестами или чартами.
Приложение — это набор ресурсов Kubernetes и основная единица управления. Оно определяет источник манифестов, целевой кластер и синхронизацию между желаемым и фактическим состоянием кластера. Проекты позволяют организовывать приложения в логические группы для управления доступом (ограничение пользователей и групп), источниками и целями (манифесты и кластеры), а также применением общих политик (синхронизация, обновление).
Argo CD имеет удобный и понятный интерфейс для работы. Можно посмотреть текущее состояние синхронизации приложений, сравнить настоящую и прошлую ревизии (diff), изучить логи.

Интрефейс Argo CD.
В условиях современной разработки, где проекты могут быть сложными и разнообразными, а инфраструктура постоянно меняется, возникает необходимость в унификации процессов. Представьте, что нужно развернуть проект, который не обновлялся несколько лет, или перенести его в другой кластер, при этом не нарушив уникальный процесс развертывания. Еще частый источник путаницы и затрудненного управления — использование в каждом проекте собственного пайплайна.
В таких ситуациях выручает GitOps, который унифицирует процессы для всех проектов, независимо от особенностей сборки. Вместо настройки сложных пайплайнов используется простой и элегантный способ: достаточно доставить новый тег Docker-образа в GitOps-репозиторий — и приложение автоматически разворачивается в кластере.
В следующем примере клонируется репозиторий. Поле app.image_tag в файле _values.yaml получает новое значение на основе короткой SHA‑суммы текущего коммита. В завершении изменения фиксируются в репозитории, а новый коммит получает информативное описание:
.deploy_template:
stage: deploy
image: $CI_REGISTRY/tools/yq:1.0.0
script:
- git clone "https://$USER:$TOKEN@$GITOPS_REPO_URL" gitops
- cd gitops
- yq -i ".app.image.tag = strenv(CI_COMMIT_SHORT_SHA)" ${GITOPS_CATALOG}/${GITOPS_NAME}/values.yaml
- git config --global user.email "deploy@example.ru"
- git config --global user.name "GitLab CI"
- git commit -am "CI Deploy ${CI_PROJECT_NAME} - ${CI_COMMIT_SHORT_SHA}"
- git push
Значение нового тега вставляется в values нашего Helm-чарта, после чего Argo CD синхронизирует изменения в репозитории, и ресурсы в Kubernetes обновляются.
Наш путь
Итак, подытожим, обобщив подход для управления инфраструктурой и развертывания приложений.
Мы сознательно отказались от использования монорепозитория. Вместо этого репозитории разделены. В одном хранится исключительно исходный код приложения, в другом — только конфигурационные файлы, описывающие желаемое состояние инфраструктуры.
Для управления множественными зависимостями мы используем Umbrella-чарты, которые хранятся в GitLab Package Registry.

Модель деплоя Argo CD.
Преимущества Argo CD
Все недостатки связаны с необходимостью выделять время на настройку, оптимизацию пайплайнов, а также создание универсальных чатов в нашем случае.
Внедрение GitOps-подхода и использование Argo CD позволили нам унифицировать пайплайны. Это значительно сократило время, затрачиваемое на поддержку и обновление наших проектов.
Мы успешно решили проблему configuration drifting, которая часто возникала при использовании традиционных методов развертывания. Конфигурация наших приложений всегда соответствует желаемому состоянию, описанному в репозитории. Новая архитектура и использование Kubernetes обеспечивают возможность масштабировать наши приложения на любое количество кластеров.
Argo CD — мощное средство. Однако его эффективное использование требует глубокого понимания особенностей управления Kubernetes. Здесь оказывается полезным Managed Kubernetes [15] — специальный сервис, предоставляемый Selectel. Он снимает с разработчиков бремя управления инфраструктурой и позволяет сосредоточиться на реализации и развертывании приложений. Автомасштабирование, автовосстановление, обновление, мониторинг и обеспечение безопасности кластера в соответствии со 152‑ФЗ — все эти заботы берет на себя облачная платформа.
Сочетание Argo CD и Managed Kubernetes максимально упрощает и автоматизирует весь цикл жизни приложения от разработки до эксплуатации, что снижает операционные расходы. Подробнее о функциональности сервиса и его особенностях можно прочитать в онлайн‑документации Selectel [16].
Подписывайтесь на каналы Hilbert Team [17] и Selectel [18], чтобы не пропустить выход новых материалов.
Автор: devops_ht
Источник [19]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/selectel/411438
Ссылки в тексте:
[1] от Hilbert Team: https://ru.hilbertteam.com/?utm_source=habr&utm_medium=article&utm_campaign=argocd
[2] GitLab и Push‑модель: #push-models
[3] Kubectl: #kubectl
[4] Kustomize: #kustomize
[5] Helm: #helm
[6] Helmfile: #helmfile
[7] Сравнение: #comparison
[8] Pull-модель, GitOps и Argo CD: #pull-models
[9] Предпосылки к использованию нового подхода: #prereqisities
[10] Argo CD: #argocd
[11] Унификация деплоя: #unification
[12] Заключение: #conclusion
[13] Регистрируйтесь: https://promo.selectel.ru/multihacker/?utm_source=habr.com&utm_medium=referral&utm_campaign=comics_article_argocd-and-deploy-strategy_190225_content
[14] Что такое GitOps? Краткий обзор методологии и знакомство с ArgoCD: https://selectel.ru/blog/gitops-argocd/?utm_source=habr.com&utm_medium=referral&utm_campaign=academy_article_argocd-and-deploy-strategy_190225_academy
[15] Managed Kubernetes: https://selectel.ru/services/cloud/kubernetes/?utm_source=habr.com&utm_medium=referral&utm_campaign=cloud_article_argocd-and-deploy-strategy_190225_content
[16] в онлайн‑документации Selectel: https://docs.selectel.ru/cloud/managed-kubernetes/?utm_source=habr.com&utm_medium=referral&utm_campaign=docs_article_argocd-and-deploy-strategy_190225_content
[17] Hilbert Team: https://t.me/+07Hc3hVVX_44YzYy
[18] Selectel: https://slc.tl/11lv9
[19] Источник: https://habr.com/ru/companies/selectel/articles/883650/?utm_source=habrahabr&utm_medium=rss&utm_campaign=883650
Нажмите здесь для печати.