Привет, Хабр! Это вторая часть большой статьи, где мы — Егор Салиев и Николай Пушкарев, DevOps-инженеры Hilbert Team, — рассказываем, как построить GitOps-платформу на Argo CD.

В первой части разобрали базу: познакомились и установили Argo CD, изучили его компоненты и показали установку через Helm и Terraform. В этой — перейдём к практике и ответим на вопрос, что делать, когда команда растёт вместе с количеством приложений и усложняется инфраструктура. Пройдём по сценариям от маленькой команды до большой организации и соберём рабочую GitOps-модель на Argo CD.

Application для небольшого сервиса и первый шаг к GitOps

Представим, что мы — небольшая команда или стартап. С чего начать движение в сторону GitOps при скромных масштабах?

Начнём с малого — и этого уже будет достаточно для первого шага к улучшению деплоя:

  • Маленький бэкенд

Бэкенд занимается довольно простой, но важной задачей — складывает два числа.

  • Helm-чарт

Делаем helm install и немного адаптируем под свои нужды. И добавим Ingress, чтобы можно было взаимодействовать с приложением извне.

  • Application

На текущем этапе нам вполне хватит базового ресурса Application. Даже один такой ресурс — уже шаг в сторону более совершенного деплоя.

Практика: Application «для маленьких»

Как работает ClickOps-подход

После установки Argo CD пора поднять первое приложение. Проще всего это сделать через веб-интерфейс — это и есть современный ClickOps-подход: нажимаем + New App и создаём приложение:

Что здесь важно:

  • название приложения,

  • проект, к которому оно относится,

  • политика синхронизации,

  • галочки: создавать namespace автоматически, применять изменения от имени Argo CD сервера,

  • репозиторий-источник, ревизия (ветка), путь в репозиторий,

  • и, конечно, кластер, в который это всё должно задеплоиться.

Но ClickOps — не тот метод. Мы просто показали, как это выглядит. На практике используем подход YAML-инжиниринга, в рамках которого создаём yaml-файлы вместо того, чтобы кликать в интерфейсе.

ArgoCD IaC

Все наши Argo CD-компоненты лежат в папке components, где уже есть проекты для логического разделения. В этой же папке создаём первый Application:

Внутри указываем то же самое, что и в веб-интерфейсе:

  • проект, к которому относится Application;

  • репозиторий и путь (source repository);

  • кластер назначения (destination cluster);

  • политику синхронизации.

Мы используем Kustomize, поэтому применяем всё сразу скопом и устанавливаем. Argo CD создаёт приложение. Проверяем результат: namespace default, всё появилось. Ingress — тоже работает.

Итак, можно создать одно приложение, один YAML-файл, один ресурс Argo CD. Но что, если мы вырастем и появится 10, 50 или 100 окружений, микросервисов, команд? Создавать Application вручную для каждого — неудобно. Поэтому переходим к ApplicationSet, более мощному инструменту шаблонизации, с помощью которого можно генерировать Application-ресурсы автоматически.

Практика: ApplicationSet для большой команды

Итак, компания растёт — появляются новые команды и окружения. Бэкенд обрастает зависимостями: появляется Redis, RabbitMQ, PostgreSQL. Возникает вопрос — как всё это разворачивать? Вот какие подходы существуют:

  • Создать Application для каждого сервиса

Теоретически можно. Но создавать и поддерживать отдельный Application-ресурс отдельно для каждого приложения — не рационально.

  • Использовать App-of-Apps

В этом случае берётся один Application, который смотрит на репозиторий, где лежат другие Application-ресурсы, и они автоматически разворачиваются. У Argo CD под этот подход есть готовый helm-чарт, который можно адаптировать под свои нужды. Но в таком случае мы будем ограничены функционалом ресурса Application.

  • Использовать ApplicationSet

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

Generators

Внутри ApplicationSet есть важная механика — Generators. В официальной документации описано девять видов генераторов. Мы рассмотрим четыре:

  1. Git Generator — используется чаще всего. С его помощью ApplicationSet определяет, на основе чего генерировать шаблоны Application. Смотрит на конкретный Git и ​​с какой веткой работать.

  2. Cluster Generator — генерирует Application-ресурсы  на основе кластеров, которые обслуживаются в Argo CD.

  3. Matrix Generator — позволяет комбинировать разные генераторы.

  4. SCM Provider Generator — один из самых мощных. Он взаимодействует с Git через API, позволяет читать ветки, применять фильтры по именам, владельцам и прочее.

В зависимости от задач можно выбрать что-то подходящее.

SyncPolicy — ещё одна киллер-фича ApplicationSet

Представим, вы выкатили пять приложений через ApplicationSet. Всё сгенерировалось и работает. Но если вы случайно удалите сам ApplicationSet — всё исчезнет, наступит полная дезинтеграция.

На этот случай есть настройка syncPolicy. Если при генерации вы укажете параметр preserveResourcesOnDeletion, то у тех Application, которые были сгенерированы, не будет финалайзера. А значит, при удалении ApplicationSet они останутся жить.

В каких-то продовых средах это может быть критично: такая настройка спасает от случайного удаления приложений. 

В целом, ApplicationSet — настраиваемый ресурс. Посмотрим, как он работает.

ApplicationSet ДЛЯ БОЛЬШИХ live

В этом примере все ApplicationSet уже развёрнуты в Argo CD, и в основном это инфраструктурные приложения:

Что здесь интересного:

  • Во-первых, preserveResourcesOnDeletion — та самая волшебная опция, которая защищает от удаления Application.

  • Блок generators — мы используем Git-генератор. Как и в обычных Application, здесь есть source-репозиторий, ревизия и какие директории будут использоваться. Каждый ApplicationSet — это отдельный репозиторий, поэтому в пути указывается *.

  • Для шаблонизации имени используется path.basename — имя директории.

  • Также указывается проект, к которому относится ApplicationSet, и политика синхронизации.

Укажем опцию preserveResourcesOnDeletion в блоке spec.template.spec.syncPolicy.syncOptions. На всякий случай она присутствует и в блоке spec.syncPolicy

  • Дальше — source-репозиторий и destination-кластер.

Поскольку мы используем плагин helm-secrets, для источника helm-charts нужно указывать не просто values.yaml, а строку с ключом шифрования:

Итак, ApplicationSet создался:

Он берёт шаблоны из репозитория backend, где находится зонтичный чарт (umbrella chart) и его values. На этот момент всё, что мы разворачиваем, хранится в приватном Helm-репозитории. Это касается как инфраструктурных чартов, так и самописных приложений.

Имя Helm-репозитория мы указываем прямо в манифесте — main-helm-repo,— и это просто короткая ссылка на репозиторий:

Как приложение обновляется через GitLab CI

Наше приложение уже имеет более-менее сложную структуру. Теперь нужно его интегрировать с GitLab и настроить процесс обновления.

У нас два репозитория:

  1. GitOps-репозиторий с конфигом приложения, который будет развиваться в кластере.

  2. Репозиторий с исходным кодом, где работают разработчики.

Посмотрим, как код будет доставляться в кластер через GitLab CI.

Вот шаблон deploy_template:

```yaml
.deploy_template:
  stage: deploy
  image: hilbertteam.gitlab.yandexcloud.net:5050/hilbert-team/devopsconf2025/argocd-worshop/docker/yq:1.0.0
  script:
    - git clone "https://$GITOPS_REPO_TOKEN_NAME:$GITOPS_REPO_ACCESS_TOKEN@$GITOPS_REPO_URL" gitops
    - cd gitops
    - yq -i "$VALUES_PATH = strenv(IMAGE_TAG)" ${GITOPS_CATALOG}/values.yaml
    - git config --global user.email "argoworkshop@hilbertteam.com"
    - git config --global user.name "GitLab CI"
    - git commit -am "CI Deploy ${CI_PROJECT_NAME} - ${IMAGE_TAG}"
    - git push
  tags:
    - k8s-infra
```

Мы используем yq (Yaml Query), но можно и другой. У большинства образов с yq по умолчанию нет установленного git, так что его нужно поставить вручную. В результате происходит следующее:

  • Клонируется GitHub-репозиторий.

  • Мы переходим в нужную папку.

  • С помощью yq инжектим тег нового образа в файл values.yaml.

  • Выполняются git config, git commit и git push.

Кому-то может не нравиться git push, потому что мы пушим в main-ветку, но на самом деле это не так критично. Это всё-таки GitOps репозиторий, а не репозиторий с исходным кодом. В качестве альтернативы можно использовать git switch и git commit с автоматическим созданием merge request в целевую ветку.

Переменная VALUES_PATH — это просто название строки, куда подставляется тег в values. Тег меняется, и Argo CD синхронизирует изменения.

Посмотрим на pipeline — например, прошедший деплой:

При билде забавы ради используем автотег. Но вообще, при таком способе деплоя лучше использовать либо CI_COMMIT_TAG, либо короткий хэш коммита — это удобнее для тестирования. Не стоит использовать имя ветки (CI_COMMIT_REF_SLUG), потому что джоба упадет с ошибкой, что «нечего коммитить».

Теперь проверим, какая версия сейчас установлена в Argo CD. Просто выполняем refresh в интерфейсе Argo CD: новый тег улетел, Argo CD подхватил изменения, приложение обновилось.

На этом мы закончили с ApplicationSet и настройкой деплоя. Теперь двигаемся дальше: компания растёт ещё больше, нужно усложняться и как-то контролировать доступ к Argo CD.

Практика: Контроль доступа и статические роли

Argo CD поддерживает RBAC-модель. Она немного отличается от привычной Kubernetes-модели — в частности, другим синтаксисом.

Выглядит следующим образом: есть какие-то действия, которые можно производить с объектами (get, create, update, delete и т.д.), и есть сами объекты (Application, ApplicationSetCluster, Repository и другие). Эти действия выполняют субъекты — пользователи или группы пользователей.

Посмотрим, как это работает.

Контроль доступа. Статические роли (live)

Посмотрим, как настраивается политика доступа в Argo CD. Для этого в конфигурации values.yaml нужно задать блок:

argo-cd:
  configs:
    rbac:

Здесь мы создаём политики. Их может быть несколько, и все они объединяются в общий конфиг. Вот пример, как настраиваются статические роли:

  • all-admins — ресурс Argo CD accounts, действия, которые мы хотим сделать, и название проекта.

  • infrastructure-admins могут делать что угодно с Applications в проекте инфраструктуры.

  • Backend-admins могут делать что угодно с Applications в проекте бэкенда.

  • Backend-readonly могут только синхронизировать и смотреть логи у приложений в проекте backend.

Практика: контроль доступа SSO с Dex+Keycloak

Дальше структура усложняется. Было 30 человек — стало больше, потом ещё больше. И в какой-то момент пользователей становится так много, что уже непонятно, как организовывать доступы.

На этом этапе останавливаемся, потому что нужен единый источник аутентификационных данных. Выбираем для этого Keycloak.

Возникает вопрос: можно ли настроить сквозную авторизацию, то есть SSO между Argo CD и Keycloak? Ответ — да, это можно реализовать напрямую. Мы же сейчас рассмотрим другую схему — с использованием Dex.

Dex идёт в составе стека Argo CD и играет роль OIDC-прокси. Что происходит при авторизации:

  1. Пользователь заходит в Argo CD и пытается авторизоваться через SSO.

  2. Argo CD перенаправляет его в Dex.

  3. Dex, в свою очередь, переадресует пользователя в Keycloak — наш Upstream Identity Provider.

  4. Пользователь проходит авторизацию в Keycloak и получает соответствующий токен и группы, привязанные к токену.

  5. Всё это возвращается в обратном порядке: Keycloak → Dex → Argo CD.

Argo CD на основе полученных групп предоставляет доступ.

Контроль доступа SSO с Dex+Keycloak (live)

Сначала устанавливаем Keycloak: через Argo CD → проект инфраструктуры → Keycloak.

Keycloak нужна база данных, у нас это PostgreSQL. Оба этих проекта уже успешно развернулись:

Дальше нужно настроить Keycloak:

  • Создаём Realm — argo-cd:

Эту настройку мы делали не через Terraform Provider, а вручную.

  • Создаём клиент Argo CD:

  • Указываем адрес Argo CD: home URL (по умолчанию открывается через Applications). 

  • Настраиваем redirect URI. В случае, если мы подключаемся к OIDC напрямую, то путь такой: /auth/callback 

Если через Dex, то путь другой — /api/dex/callback.

Post logout redirect и admin URL — такие же, как home URL

Web origins — зависит от CORS. В нашем случае достаточно просто указать *.

  • Далее нам нужен clientSecret— копируем его, он пригодится при настройке:

  • Создаём Client Scopes-группы, чтобы маппить группы из Keycloak в Argo CD напрямую:

  • Делаем этот scope дефолтным и добавляем его в созданного клиента:

Вот мы его добавили:

Теперь создаём группы:

  • argocd_admins

  • argocd_readonly

  • backend_admins

  • backend_readonly

  • infrastructure_admins

  • Создаём пользователей и распределяем их по группам:

Переходим к настройке OIDC в Dex:

  • Выносим values для настройки Dex в отдельный файл:

В конфиг-мапу добавляется dex.config:

  • тип коннектора: oidc;

  • id: keycloak;

  • name: любое, например Dex-Keycloak;

  • issuer: адрес вашего realm в Keycloak;

  • clientID

  • clientSecret — этот секрет не вставляем в открытом виде, он идёт из секретного зашифрованного файла;

  • scopes: добавляем стандартные плюс groups.

На этом настройка закончена. Применяем конфигурацию и ждём, пока Argo CD обновится.

Готово! В интерфейсе появилась кнопка LOG IN VIA DEX — подпись можно сделать любой.

Пробуем зайти под argo-admin.

Политика доступа: пользователь argo-admin — полноценный админ. Он может делать с объектами, что угодно: смотреть репозитории, видеть кластеры.

 Но не может посмотреть сертификаты и ключи:

Давайте это поправим.

Допустим, у нас тип доступа get, ресурс — certificates и ключи — gpgkeys. Сначала указываем ресурс, потом действия:

Теперь argo-admin может смотреть сертификаты и ключи. Наш админ больше не неполноценный.

Это был кейс проверки и настройки RBAC.

Теперь попробуем зайти под backend-user:

Backend-юзер видит только проект backend. Может просматривать приложения, но не удалять. 

На этом мы завершили настройку SSO и RBAC.

Отметим, что настройки доступа можно указывать не только в файле values.yaml, но и также в проектах. В каждом проекте настраиваются нужные политики доступа, чтобы они не захламляли основной файл.

Практика: организация доставки секретов

Теперь разберём, как организовать доставку секретов к приложениям.

Для хранения секретов мы выбрали один из самых популярных инструментов — HashiCorp Vault.

Для интеграции с Vault в Argo CD есть плагин AVP (Argo Vault Plugin). Когда вы его устанавливаете, компонент RepoServer получает возможность обращаться к Vault и на основе плейсхолдеров получить из него данные секрета.

Но есть негативный нюанс: RepoServer действует от имени токена, который никак не гранулирует уровни доступа к секретам. Если вы дали токену доступ к Vault — он сможет читать все секреты, разрешённые политикой.

Мы в проектах перешли на использование Bank-Vaults. Во-первых, это «швейцарский нож» для решений с Vault. Во-вторых, его фишка — механизм Secret Injector Webhook, позволяющий получить гранулированный доступ к разным папкам с секретами, и секьюрный способ доставки секрета к приложению.

Как это работает (немного слайдов из документации):

  • Вы навешиваете на приложение специальные аннотации.

  • На их основе оператор добавляет к ним Init Container контроллер и бинарник vault-env.

  • ​​Этот бинарник, используя токен, идёт в Vault за секретом. При этом в env-приложение вы подкладываете плейсхолдер, при котором компонент понимает, по какому адресу нужно получить секрет.

  • Секрет не попадает напрямую в основной контейнер. Он живёт в переменном окружении vault-env, и уже оттуда передаётся в конкретное приложение, запущенное в поде.

Организация доставки секретов (live)

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

В нашем случае он установлен оператором. Бэкенд — Postgres, та же самая база, что используется для других компонентов. Настройки подробно рассматривать не будем.

Посмотрим, что у нас в vault-secrets-webhook:

Из репозитория с helm-чартами разворачиваем vault-secrets-webhook и указываем переменные:

  • внутренний адрес Vault;

  • путь авторизации Kubernetes (VAULT_PATH);

  • SKIP_VERIFY — не нужен, так как у нас Vault с TLS, и есть файл с секретом.

Vault развёрнут. Включаем тип доступа к Kubernetes:

Здесь нужен только адрес Kubernetes API. Никаких дополнительных настроек не требуется, но только в том случае, если Vault находится в том же Kubernetes-кластере. Для внешнего кластера другая история, она описана в документации.

Создаём роль для приложения, назовём её test-app:

Указываем имя сервисного аккаунта (в нашем случае сервисный аккаунт приложения — дефолтный в frontend и backend namespace). Также создаём политику доступа этой роли:

Когда Vault и Vault Secrets Webhook готовы и развёрнуты в кластере, переходим к настройке самого приложения. Добавляем аннотации, которые используются

```yaml
vault-secrets-webhook:
  annotations:
    vault.security.banzaicloud.io/vault-addr: "https://vault.vault.svc.cluster.local:8200"
    vault.security.banzaicloud.io/vault-role: "test-app"
    vault.security.banzaicloud.io/vault-skip-verify: "true"

Так он поймёт, что к этому приложению нужно добавить свой Init Container. Здесь указываем:

  • адрес Vault,

  • нужную роль,

  • и на всякий случай — skip_verify.

Любой из этих аннотаций достаточно, чтобы Vault Secrets Webhook применился к нужному контейнеру.

Теперь — переменные окружения. Вместо значений указываем плейсхолдеры в формате:

envsToCM:
  DB_USER: vault:secret/data/test/backend/test-app#DB_USER
  DB_PASSWORD: vault:secret/data/test/backend/test-app#DB_PASSWORD

После # можем указать название секрета в Vault, потому что оно может отличаться, и версию этого секрета (1, 2, 3 и т.д.).

Что происходит при запуске приложения

Сначала стартует Init Container, копия vault-env — он копирует бинарник Vault:

Как видите, переменные окружения не мутировали, то есть здесь нет секретных значений:

На самом деле они попали в PID первого процесса. Посмотрим на PID 1:

Видим значение. Его также можно посмотреть другим способом:

Как видим, секрет успешно доставлен.

Практика: Argo Rollouts. Стратегии Progressive Delivery

Argo Rollouts — это инструмент, позволяющий реализовать стратегии Progressive Delivery (в общем случае это процесс инкрементального обновления ресурсов, их тестирование и последующий rolling update), подхода к деплою приложений.

К Progressive Delivery относятся такие стратегии, как:

  • Blue/Green,

  • Canary,

  • A/B Testing,

  • Feature Flags и другие.

Argo Rollouts работает только с двумя — Blue/Green и Canary.

Blue/Green — по сути, расширенная версия Rolling Update, к которой добавлены механизмы Analysis Template. Эта стратегия позволяет развернуть новую версию приложения (Green), не прерывая работу текущей версии (Blue). На основе шаблонов с метриками или скриптов можно оценить состояние нового приложения. И если есть Green-реплики, и всё положительно, переключить трафик со старой версии на новую.

Canary — стратегия более гибкая и сложная. Она особенно полезна, когда у приложения много реплик, и нужно постепенно расписать, на какой процент будет переключаться трафик на каждой ступени.

На каждую ступень можно накидывать Analysis Template, чтобы собирать метрики и отслеживать, всё ли идёт по плану. А если метрики «проседают», автоматически и бесшовно откатиться на Blue-версию приложения.

Argo Rollouts. Стратегии Progressive Delivery (live)

Посмотрим пример использования Argo Rollouts с учётом template.

Чтобы использовать Argo Rollouts, его сначала нужно развернуть. Мы добавили его в проект infrastructure как обычный helm-чарт, который скачали с официального сайта, и положили в свой репозиторий.

Здесь почти ничего интересного, кроме дашборда, который у Argo Rollouts есть по умолчанию:

Добавляем chart в GitOps-репозиторий:

Развернулся он своеобразно: авторизации нет, экран серый, что-то крутится, но ничего не нажимается. Работает, но ощущение — будто зависло.

Теперь попробуем развернуть первый Rollout.

На самом деле, Rollout отличается от обычного Deployment только названием.

У нас есть Helm-чарт для бэкенда на golang, и в нём — обычный Deployment. Мы просто берём его и с помощью Ctrl+C / Ctrl+V переименовываем в Rollout. То есть:

  • меняем apiVersion,

  • и kind: Deploymentkind: Rollout.

{{- if .Values.app.strategy -}}
{{- $pvc := list "pvc" "PVC" -}}
apiVersion: argoproj.io/v1alpha1
kind: Rollout

Чтобы это работало, мы добавили условия:

  • если в values указана (и заполнена) стратегия → Rollout;

  • если стратегия не заполнена → Deployment.

{{- if not .Values.app.strategy -}}
{{- $pvc := list "pvc" "PVC" -}}
apiVersion: apps/v1
kind: Deployment

На наш взгляд, это логично, потому что в простом деплойменте стратегия редко указывается явно.

Теперь превратим бэкенд из обычного Deployment в Rollout. Для этого заполняем блок стратегии и указываем canary. Раскомментируем выделенный кусок (на скриншоте ниже), и будем использовать:

Внутри стратегии:

  • название;

  • сервис, который будет вести на бэкенды;

  • шаги — например, setWeight: 50, что при двух репликах означает: трафик будет делиться 50 на 50, и одна реплика уйдёт со stable на canary. Этот шаг длится 60 секунд (duration: 60).

Применяем изменения, заходим в Argo CD, рефрешим backend:

Теперь это Rollout, а не Deployment:

Так как он запустился впервые, оба шага проскочили сразу и все реплики стали stable. В интерфейсе Argo Rollouts появился Rollout и загрузка перестала быть бесконечной:

Нюанс: этот интерфейс — read-only. Кнопки нажимаются, но ничего не происходит — авторизации нет. Никто не сможет случайно удалить или откатить Rollout вручную:

К счастью, в Argo CD после установки Rollouts появляется новая одноимённая сущность, которой можно управлять из интерфейса. С ней можно полноценно работать: выполнять RESUME, RESTART и так далее:


Проверим, как это работает на деле. Допустим, мы обновили версию. Обновляем бэкенд в Argo CD — смотрим, что происходит:

Теперь у нас две реплики и два бэкенда:

Через минуту, если всё хорошо, поднимутся две реплики нового релиза, и старая ревизия удалится:

Если мы не укажем здесь длительность паузы между выкаткой новых реплик, то пауза будет бесконечной до того, как вы вручную не промоутите Rollout. Чтобы всё это не делать руками, можно автоматизировать через GitLab CI

Для этого в наш пайплайн с бэкендом добавим две новых джобы — promote и rollback:

На стейдже Argo CD предлагает свой образ для CI/CD, но он неподходящий:

  • работает только с CLI-командами,

  • требует shell, которого в GitLab Runner обычно нет.

Поэтому можно использовать любой image, допустим, тот же helm-kubectl. Главное — скопировать туда бинарник argo-rollouts.

Итак, что за стейджи и джобы в CI? Всё просто:

  1. Проверяем состояние Rollout.

  2. Если всё хорошо — промоутим.

  3. Снова проверяем состояние.

  4. Если что-то пошло не так — откатываемся на предыдущую версию.

Если не хочется выполнять вручную, можно использовать Analysis Templates или Cluster Analysis Templates.

Templates используют разные провайдеры. Например, Prometheus — собирает метрики и проверяет, всё ли ок, либо job — завершается успешно или неуспешно, либо Web — делает запрос на веб-адрес сервиса. Мы можем парсить этот JSON, смотреть на data, ОК, или не ОК.

Для примера возьмём провайдер job. Документация Argo CD предлагает для тестов простую команду, которая будет фейлиться с вероятностью 50/50:

Создаём такой Analysis Template, называем его fail, и смотрим, как поведёт себя Rollout.

Чтобы все изменения сработали, обновляем версию приложения и заходим в Argo CD:

Запускается canary стратегия, job выполняется и… падает:

Результат: AnalysisRun упал → новая ревизия не сработала → бэкенд откатывается на предыдущую версию:

Что будет, если всё-таки AnalysisRun будет успешным? Чтобы это проверить, сделаем обратное:

  • меняем template на заведомо успешный;

  • меняем версию;

  • синхронизируем изменения в Argo CD;

  • смотрим на результат в Argo Rollouts.

На этот раз AnalysisRun прошёл успешно и вторая реплика автоматически переводится в статус stable.

Итоги

Пытаясь объяснить работу GitOps на практике, мы разбили большую тему на две статьи. В первой части закладывали фундамент — устанавливали Argo CD, настраивали helm-secrets, подключали Terraform и разбирались, что такое Application и ApplicationSet. В этой перешли от теории к практике: задеплоили первый бэкенд, показали на сценариях разного масштаба, как GitOps-решение эволюционирует вместе с ростом команды. Автоматизировали деплой через CI и обеспечили безопасную доставку секретов с помощью Vault.

В результате прошли путь от простого приложения до продвинутых сценариев с RBAC, SSO и Progressive Delivery на Argo Rollouts, где было важно всё: структура репозиториев, размер команды, доступы, безопасность и другие параметры. 

Материалы по установке и настройке Argo CD можно найти в GitHub-репозитории воркшопа. А чтобы разобраться в GitOps глубже, задать вопросы практикам и обсудить, как подступиться к своей платформе — приходите на DevOps Conf. Поговорим о реальных кейсах, архитектуре, которая работает, и инструментах, которые упрощают жизнь инженеров. 

Спасибо, что дочитали нашу статью до конца. Не забывайте подписываться на телеграм-канал Hilbert Team

Скрытый текст

А чтобы узнать больше по теме, приходите на DevOps Conf 2026 — здесь сконцентрированы энергия и бесценный опыт лучших инженеров, CTO, CIO, техлидов и тимлидов. Вас ждет расширение профессионального кругозора, обсуждение практических вопросов, отработка навыков на мастер-классах и много-много нетворкинга.

Комментарии (0)