07 июл. 2025 г.·7 мин

GitOps в закрытом контуре: Argo CD vs Flux для деплоя

GitOps в закрытом контуре помогает деплоить без прямого доступа в кластер: сравним Argo CD и Flux, разберем среды, аудит и контроль изменений.

GitOps в закрытом контуре: Argo CD vs Flux для деплоя

Задача: деплой без прямого доступа в кластер

Формулировка «инженеры без доступа в кластер» на практике означает простую вещь: разработчики и DevOps не заходят в Kubernetes через kubectl, не имеют прав на создание и изменение ресурсов и не могут «подправить» прод руками. Кластер живет в закрытом контуре (air-gapped), а изменения попадают внутрь только по заранее заданному каналу и по правилам.

Обычно это требование появляется не из любви к запретам, а из попытки закрыть конкретные риски. Чаще всего речь о трех вещах: человеческие ошибки (не тот namespace, не та версия, случайно удалили), инсайдерские действия (умышленная правка) и «одноразовые» изменения, которые потом никто не может повторить или объяснить.

Ручной деплой и схема «выдадим доступ на час» быстро перестают работать. По мере роста команд и сервисов становится сложно контролировать, кто и что делал, а временные доступы превращаются в постоянные исключения. А любая авария провоцирует ручные правки, которые не попадают в историю и ломают воспроизводимость.

Ожидания ИБ обычно звучат так: должно быть понятно, кто изменил конфигурацию, что именно изменилось, когда это произошло и по какой причине. Идеально, если это не скриншоты из чата, а цепочка вида: заявка или задача - изменение в Git - проверка - применение - подтверждение результата.

Простой пример: команда хочет обновить сервис с версии 1.2.3 на 1.2.4 и добавить переменную окружения. В хорошем процессе у инженера нет кнопки «применить прямо сейчас». Он меняет конфигурацию в репозитории, проходит проверки и согласования, а дальше система внутри контура сама подтягивает и применяет ровно то, что описано в Git, оставляя понятный след для аудита.

GitOps в двух словах и что он дает в закрытом контуре

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

Обычно манифесты (Helm, Kustomize, plain YAML) лежат в отдельном репозитории или в папке рядом с кодом. Поток выглядит так: инженер делает изменения, открывает PR, проходит проверку и ревью, затем делает merge. После merge GitOps-контроллер подтягивает новую версию конфигурации и применяет ее в нужной среде.

В изолированной среде это дает несколько практичных преимуществ. Во-первых, меньше ручных действий в кластере и меньше шансов «нажать не туда» в проде. Во-вторых, появляется ясная ответственность: изменения проходят через PR и ревью. В-третьих, растет воспроизводимость: окружение можно восстановить по репозиторию. И наконец, проще разделять доступы: инженерам не нужен прямой доступ к Kubernetes.

Под аудитом в GitOps обычно понимают не только историю коммитов. Важно, чтобы сходились три слоя: кто внес изменение (автор и ревью), что именно изменилось (diff в Git) и что реально задеплоилось (артефакты CI, версии образов, теги, результаты проверок). В закрытом контуре это часто критично для внутренней безопасности и проверок.

GitOps при этом не решает все сам по себе. Секреты по-прежнему нельзя хранить в Git, значит нужны отдельные решения (шифрование, внешние хранилища, политики). И GitOps не заменяет релизный процесс и тестирование: доставка становится предсказуемой, но качество все равно зависит от CI и правил команд.

Архитектура air-gapped: что должно быть внутри контура

В закрытом контуре главный принцип простой: кластер не тянет ничего снаружи, а все, что попадает внутрь, проходит понятный контроль. Тогда GitOps работает предсказуемо: контроллер в кластере берет желаемое состояние из внутреннего Git и применяет его сам, без прямого входа инженеров.

Типовая минимальная схема внутри периметра обычно включает внутренний Git-сервер как источник манифестов и правил, CI-систему внутри контура (сборка и проверки), внутренний container registry, GitOps-контроллер (Argo CD или Flux) в Kubernetes и, при необходимости, хранилище секретов и артефактов (например, если вы используете Helm-репозитории, OCI или пакеты).

Доставка артефактов без интернета часто строится через «шлюз» обновлений: отдельную точку, где можно принять пакеты и образы, проверить их, подписать и только затем перенести в основную зону. Важно, чтобы это был регулярный и документированный процесс, а не разовая ручная операция.

Чтобы в кластере были только «разрешенные» версии, закрепите это в правилах, а не в договоренностях. Практика, которая быстро окупается: хранить образы только во внутреннем registry, запрещать pull из внешних источников и требовать подпись образа или хотя бы строгую привязку к digest. Тогда Git указывает не «latest», а конкретную проверенную сборку.

С зависимостями и базовыми образами помогает не магия, а дисциплина обновлений. Регулярно импортируйте базовые образы и пакеты во внутренние репозитории, прогоняйте сканирование и тесты в CI и фиксируйте результаты. Дальше обновляйте версии через pull request в Git, чтобы оставался след, и деплойте сначала в тестовую среду, затем в прод тем же способом.

Сценарий в итоге выглядит просто: команда собрала сервис в CI, образ попал во внутренний registry, а изменение версии попало в Git. GitOps-контроллер увидел коммит и сам применил обновление. Инженеру не нужен kubectl, а аудит видит, кто и когда поменял версию и какие артефакты были допущены внутрь.

Argo CD и Flux: принципиальные отличия

И Argo CD, и Flux решают одну задачу: кластер сам подтягивает нужное состояние из Git и приводит к нему Kubernetes. Но устроены они по-разному, и в закрытом контуре это влияет на удобство эксплуатации, безопасность и разбор инцидентов.

Argo CD ближе к модели «приложений». Вы описываете Application, а дальше инструмент показывает, что установлено, что должно быть и где расхождения. Сильная сторона Argo CD - наглядный UI и понятные статусы синхронизации. Это удобно платформенной команде, которая отвечает за несколько команд и сред: проще увидеть, что именно «красное», и быстрее вернуть систему в ожидаемое состояние.

Flux устроен как набор контроллеров и чаще воспринимается как более «Git-first» подход: ключевые сущности описываются декларативно в репозитории, а в кластере контроллеры применяют изменения. Flux нередко выбирают, когда важны компактность компонентов и минимальная зависимость от отдельного сервиса с богатым интерфейсом.

На практике различия обычно проявляются так. Дрейф состояния оба инструмента обнаруживают, но Argo CD чаще объясняют через UI, а Flux - через события и логи контроллеров. Откат в обоих случаях базовый: возврат коммита в Git, просто в Argo CD это заметнее оператору за счет истории и статусов. По модели управления Argo CD централизует работу вокруг «приложений», а Flux распределяет ее по контроллерам и ресурсам.

Для закрытого контура чаще всего важны предсказуемость и минимальные права. В обоих вариантах инженерам не нужен прямой доступ в кластер: они делают pull request, а кластер применяет изменения сам. Выбор обычно сводится к тому, что вам ближе: визуальный контроль (Argo CD) или максимально декларативная схема из отдельных контроллеров (Flux).

Как разделить среды без путаницы и ручных правок

Разделение сред в GitOps часто ломается по одной причине: начинают копировать манифесты из dev в stage и править их вручную. В закрытом контуре это особенно опасно: инженеры не заходят в кластер, поэтому любая «ручная» правка превращается в долгий поиск того, где именно разъехались настройки.

Рабочий подход - держать один источник правды для базы приложения и накладывать поверх минимальные отличия среды (реплики, лимиты, ingress, включенные фичи). Это удобно делать через Kustomize overlays или через values для Helm. Важен принцип: база общая, отличия маленькие и явные.

Структуру репозиториев обычно выбирают по компромиссу между удобством и доступами. В monorepo база и оверлеи всех сред лежат рядом, поэтому проще искать и сравнивать изменения. В multi-repo приложение и окружения разделены, что обычно строже по доступам, но требует больше координации.

Продвижение версии между средами лучше устраивать так, чтобы история была читаемой. Часто хорошо работает схема, где сборка публикует неизменяемый образ (например, по коммиту), а «промоут» происходит только через изменение Git-описания среды. Это может быть PR из stage в prod или отдельный репозиторий релизов, где каждый коммит означает новую версию для конкретной среды. Теги в Git тоже возможны, но ими сложнее управлять через код-ревью.

Самое важное - политика изменений prod. Не «кто смелее», а четкий процесс: только через PR, только с approvals и только от ограниченного круга людей (например, SRE или релиз-инженеры). Внутри PR полезно требовать минимум: описание изменения, ссылку на задачу, план отката.

Пример: команда обновляет сервис в test, меняя только образ и один параметр. После проверки тот же коммит промоутится в stage через PR. В prod попадает отдельным PR, который подтверждают два ответственных человека. Кластер подтягивает изменения из Git, а у вас остается чистая цепочка: кто, что и почему поменял.

Аудит изменений: что фиксировать и как потом разбирать

Комплексный проект с GSE
Соберем единый проект: оборудование GSE плюс системная интеграция для закрытого контура.
Запросить решение

Аудит проще, если заранее договориться, какие изменения вообще считаются «нормальными». В прод должно попадать только то, что можно показать как цепочку фактов: Git-патч, конкретный образ во внутреннем registry (лучше по digest) и параметры развертывания (Helm values или Kustomize overlays). Ручные правки в кластере стоит считать исключением и разбирать отдельно.

Минимальная дисциплина для prod среды обычно упирается в правила pull request. Не обязательно усложнять процесс, но базовые риски закрывать нужно: все изменения только через PR (без прямых push в прод-ветку), code owners на манифесты prod и общие чарты, а также как минимум два одобрения перед merge плюс обязательная проверка CI (хотя бы lint и dry-run).

Чтобы повысить доверие к источнику изменений, добавьте подпись коммитов и/или тегов релизов. Тогда в разборе инцидента видно не только «кто написал», но и то, что изменение пришло из ожидаемого процесса, а не в обход.

Для расследований нужны не только Git-логи. Собирайте логи контроллера Argo CD или Flux, события Kubernetes и, по возможности, audit logs API-сервера. Пример: в прод внезапно поменялся лимит памяти. По Git вы находите PR с правкой values, по логу контроллера - когда он применил изменение, по событиям - какие ресурсы были пересозданы и почему.

Доступы и безопасность: как жить без kubectl у инженеров

Когда инженерам нельзя заходить в кластер напрямую, безопасность становится проще только на первый взгляд. Чтобы не получить хаос из исключений и ручных деплоев, правила доступа нужно фиксировать так же строго, как манифесты. Принцип GitOps в закрытом контуре простой: люди меняют только Git, а кластер меняет только GitOps-контроллер.

У GitOps-контроллера в кластере должны быть минимальные права. Ему обычно не нужен доступ ко всем namespace и тем более к ресурсам уровня кластера. Дайте права только на те типы ресурсов и только в тех namespace, где он реально применяет манифесты. Отдельно продумайте, кто и как сможет остановить синхронизацию или откатить релиз.

Практичная модель ролей часто выглядит так: разработчики имеют запись в Git без доступа к Kubernetes; SRE или платформа администрируют GitOps-проекты и получают ограниченный admin в кластере по необходимости; эксплуатация и ИБ имеют доступ только на чтение в Kubernetes и к журналам; GitOps-контроллер работает под service account с RBAC на конкретные namespace.

Разделение по средам стоит организовывать так, чтобы случайная правка не «протекла» в прод. Самый надежный вариант - разные кластеры. Если это дорого, используйте разные namespace и отдельные GitOps-проекты, плюс запрет на кросс-namespace доступ. Для изоляции команд помогает простое правило: одна команда - один набор namespace - один набор репозиториев.

Секреты в Git почти всегда заканчиваются утечкой, даже в закрытой сети. Заранее выберите способ доставки секретов: локальный секрет-менеджер внутри контура, шифрование секретов в репозитории (с ключами вне Git) или генерация секретов в кластере по политике. Важно, чтобы ключи расшифровки были доступны только контроллеру и узкому кругу администраторов, а не всем, кто коммитит манифесты.

Пошаговая схема внедрения GitOps в закрытом контуре

RBAC и разделение сред
Введем модель доступов: люди меняют Git, контроллер применяет, права строго по namespace.
Настроить роли

GitOps в закрытом контуре проще внедрять как управляемый проект: сначала договориться о правилах, затем автоматизировать путь артефакта, и только после этого запускать прод. Так вы убираете главный риск: ручные действия в кластере, которые нельзя нормально восстановить и объяснить.

Начните с границ ответственности. Обычно разработчики отвечают за код и манифесты приложения, платформа или DevOps-команда - за шаблоны, политики и доступы, а служба ИБ - за правила промоута и аудит.

Дальше двигайтесь по цепочке. Выберите инструмент (Argo CD или Flux) и зафиксируйте, кто утверждает изменения в репозиториях и кто имеет право на промоут между средами. Поднимите внутренние Git, CI и registry внутри контура и опишите путь образа от сборки до кластера (включая подпись образов и правила хранения). Определите структуру репозиториев и правила pull request: где живут базовые манифесты, где оверлеи dev/test/prod, и как именно происходит промоут (например, через изменение тега образа или через отдельный репозиторий окружений). Установите Argo CD или Flux в кластер с минимальными правами: отдельный namespace и строго ограниченные роли на применяемые ресурсы. Настройте наблюдаемость: история синхронизаций, алерты на drift и падение health, а также понятный откат (revert коммита или переключение на предыдущий тег).

Затем сделайте пилот на одном сервисе и закрепите регламент: кто и как оформляет изменения, сколько approvals нужно для prod, что считается аварийным откатом. Например, в закрытом контуре госоргана можно начать с внутреннего сервиса, где CI кладет образ в локальный registry, а выпуск в prod происходит только после PR в репозиторий окружения, без доступа инженеров в кластер.

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

Частые ошибки и ловушки при переходе на GitOps

Самая частая проблема в GitOps в закрытом контуре - когда среды начинают «протекать» друг в друга. В результате прод неожиданно получает тестовые переменные или образ, который не проходил нужные проверки. Обычно это происходит из-за одной общей папки манифестов, копирования файлов вручную и разного понимания того, что именно считается источником истины.

Вторая типичная ловушка - «промоут» релиза через ручные правки. Например, инженер меняет тег образа прямо в prod-ветке, потому что так быстрее. Это ломает трассировку: непонятно, кто и почему продвинул версию, и как повторить тот же шаг в следующий раз.

В первые недели внедрения полезно держать фокус на нескольких вещах. Разделяйте конфиги сред явно (директории или репозитории) и заранее решите, что может меняться в dev/test и что запрещено в prod. Продвигайте версии только изменением версии (тега, digest, chart version), а не точечными правками манифестов. Не выдавайте GitOps-контроллеру лишние права: cluster-admin по умолчанию почти всегда избыточен. И заранее выберите способ хранения и обновления секретов и сертификатов, иначе процесс упрется в согласования и ручные исключения.

Еще один частый пробел - откат и ответственность. Должно быть заранее понятно, кто делает rollback, по какому сигналу (алерт, метрики, регрессия) и к какой версии возвращаться. Если релиз в prod ухудшил время ответа, а правила «возврат на предыдущий подтвержденный commit/тег» нет, команда начинает спорить и теряет время вместо того, чтобы быстро вернуть рабочую версию и разбираться уже после.

Быстрый чеклист перед запуском в prod

Перед первым продовым релизом в закрытом контуре стоит остановиться и проверить базовые вещи. Это экономит часы на разбор инцидентов, когда доступ к кластеру ограничен, а менять нужно быстро и аккуратно.

Проверьте, что у вас есть единый источник правды: один основной репозиторий (или понятная схема из нескольких), фиксированные правила именования и ясная структура директорий по приложениям и средам. Убедитесь, что промоут dev -> test -> prod устроен без ручных правок манифестов: меняется только то, что должно меняться (например, версия образа или ссылка на пакет), а параметры среды не перетирают друг друга случайно. Для prod должны быть обязательные approvals: заранее назначены ответственные и описано, кто подтверждает изменения и по каким признакам (миграции, права, сетевые политики, ресурсы). Права GitOps-контроллера должны быть минимальны, а прямой доступ инженеров в кластер закрыт: без «обходных троп» через kubectl. И наконец, аудит должен работать на практике: логи контроллера, события Kubernetes и история Git должны позволять быстро отвечать на вопросы «кто», «что», «когда» и «почему».

Отдельно проверьте откат. Простой тест: вы выкатываете неудачную версию, затем делаете revert в Git и убеждаетесь, что система возвращает прошлую рабочую конфигурацию и сервис поднимается без ручных правок в кластере.

Пример сценария: релиз сервиса без доступа разработчиков в кластер

Инфраструктура для дата-центра
Поможем выбрать стойки, GPU и сеть для платформы, где важны контроль и воспроизводимость.
Рассчитать конфигурацию

Представим команду, где разработчики не могут писать в Kubernetes напрямую: ни kubectl, ни доступов на запись. Это типичная ситуация для GitOps в закрытом контуре, когда все изменения проходят через Git и согласование.

Разработчик меняет код и открывает pull request. После ревью CI запускает сборку, прогоняет тесты и собирает контейнер. Готовый образ уезжает во внутренний registry, а в репозитории манифестов обновляется версия образа (обычно отдельным PR на окружение dev).

Дальше выпуск становится ритуалом, который легко повторять. Дежурный или релиз-менеджер подтверждает версию для stage отдельным изменением в Git. После проверки на stage он делает такой же промоут в prod, снова через Git. GitOps-контроллер (Argo CD или Flux) подтягивает изменения и применяет их в кластере. Команда видит статус синхронизации и здоровье приложения в интерфейсе и логах, но не может случайно что-то изменить руками.

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

Откат устроен так же спокойно: вы возвращаете прошлую версию в Git (revert коммита или возврат версии образа) и ждете синхронизации контроллера. Если откат должен быть быстрым, заранее держите под рукой последнюю стабильную версию и правило: откатываемся только через Git, без ручных правок в кластере.

Следующие шаги: как начать и что можно отдать на интеграцию

Начните с простого: зафиксируйте, какие правила вам реально нужны для GitOps в закрытом контуре. Иначе выбор инструмента и схема репозиториев быстро превращаются в спор вкусов, а не в управляемый процесс.

Сформулируйте требования ИБ и эксплуатации так, чтобы их можно было проверить. Обычно полезно письменно ответить на вопросы про аудит, сроки отката, доступы и ожидания по доступности: что считается источником истины (Git, registry образов, Helm-репозиторий) и как долго хранится история, как выглядит откат (по коммиту, по тегу релиза или по заранее сохраненному артефакту), кто может одобрять изменения и как это подтверждается, какой SLA ждут от платформенной команды и поддержки.

Дальше выбирайте Argo CD или Flux под ваш рабочий стиль. Если важны визуальная проверка расхождений, ручная синхронизация по кнопке и понятный интерфейс для эксплуатации, проще стартовать с Argo CD. Если ближе подход с упором на Git и модульность контроллеров без обязательного UI, Flux может лечь естественнее.

Запускайте пилот на одном сервисе и одной команде, но с реальными правилами. Заранее задайте критерии успеха: среднее время от merge до деплоя, число инцидентов из-за конфигурации, время поиска причины по истории изменений и долю ручных действий вне Git.

Часть работ логично отдать на интеграцию: подготовку инфраструктуры внутри контура, настройку внутренних репозиториев и registries, базовую схему ролей, аудит и журналирование. Если параллельно нужно «железо» и поддержка для такого контура (включая серверы, рабочие станции и сопровождение), это можно собрать в одном проекте у GSE.kz (gse.kz) как у производителя и системного интегратора с собственной линейкой оборудования и сервисной поддержкой.

GitOps в закрытом контуре: Argo CD vs Flux для деплоя | GSE