Перейти к содержимому

Если у меня в команде кто-то делает kubectl apply напрямую в прод — это операционный инцидент с постмортемом, а не «срочно поправил». GitOps — это не «удобство», а дисциплина: git как источник истины, контроллер в кластере непрерывно сводит фактическое состояние с записанным. Правки мышкой в проде с GitOps несовместимы. Соседний лист к Infrastructure as Code под L1 Configuration Management; различие чёткое: IaC — код описывает инфраструктуру, GitOps — git как источник плюс автоматическое непрерывное сведение.

Главный навык на уровне L4 — поднять GitOps для нового сервиса так, чтобы дальше он работал без ручного вмешательства. Это значит: правильно написать манифест Application (Argo CD) или Kustomization (Flux), настроить политику синхронизации (ручную или автоматическую), включить самовосстановление и удаление лишнего. Я регулярно вижу команды, у которых GitOps стоит, но половина сервисов висит в OutOfSync, потому что настраивали впопыхах и самовосстановление не включили.

L3

  • Понимает разницу между моделью push (применяет CI) и моделью pull (контроллер подтягивает сам); находит репозиторий с желаемым состоянием своего сервиса; знает, где смотреть статус выкатки.
  • Вносит изменения через PR в этот репозиторий; понимает, что откат — это git revert; руками kubectl apply не делает.

L4

  • Поднимает GitOps для нового сервиса: пишет Application в Argo CD или Kustomization во Flux, настраивает синхронизацию, самовосстановление и удаление лишнего.
  • Разбирает проблемы синхронизации: дрейф в статусе приложения, ошибки применения, ImagePullBackOff после ночной пересборки образа. Пользуется интерфейсом Argo CD, flux get, kubectl describe и событиями.

L5

  • Проектирует структуру репозиториев: код приложения отдельно, конфигурация отдельно; окружения через наложения Kustomize или отдельные значения Helm; app-of-apps или ApplicationSet, когда приложений много.
  • Выстраивает работу с секретами: Sealed Secrets, External Secrets Operator, SOPS. Открытых секретов в репозитории не бывает никогда.
  • Встраивает постепенную выкатку: Argo Rollouts поверх Argo CD или Flagger поверх Flux. Canary и blue-green едут внутри той же схемы, а продвижение оформляется PR’ом.

L6+

  • Продумывает GitOps на несколько кластеров: схема «центр — спицы», раздача через ApplicationSet или цели Flux, переключение регионов для критичных систем.
  • Отвечает за правила игры: кто и что может менять (CODEOWNERS плюс защита веток), проверка политик через Kyverno, OPA Gatekeeper или плагины Argo CD, срок хранения журналов под требования регуляторов.
  • OpenGitOps Principles (CNCF). Канонические четыре принципа: декларативность, версионирование и неизменяемость, доставка по модели pull, непрерывное сведение. Короткий и авторитетный текст — основа любой адаптации GitOps.
  • Argo CD Documentation. Декларативная непрерывная доставка: Kustomize, Helm, Jsonnet, обычный YAML; несколько кластеров, RBAC, единый вход, журнал аудита. По моим наблюдениям, стандарт в крупных компаниях.
  • Flux (CNCF Graduated). Семейство контроллеров для Kubernetes: модель pull, минимум привилегий, разделение между командами через штатный RBAC. Альтернатива Argo CD. По моим наблюдениям, к нему чаще приходят команды, которые ценят компактную архитектуру и близость к самому Kubernetes.
  • Argo CD — контроллер с веб-интерфейсом; канонический выбор там, где на выкатку смотрят глазами и кластеров несколько.
  • Flux — только контроллеры, без интерфейса; близок к Kubernetes, движущихся частей меньше. Стандарт для своих кластеров и сценариев с несколькими командами.
  • Argo Rollouts — постепенная выкатка поверх Argo CD: canary с проверками по SLI и автоматическим откатом.
  • Flagger — постепенная выкатка поверх Flux: canary, A/B и blue-green через service mesh (Istio, Linkerd).
  • Sealed Secrets, External Secrets Operator, SOPS — секреты внутри того же потока PR.
  • Проверка политикKyverno, OPA Gatekeeper, плагины Argo CD: требования безопасности и регуляторов проверяются до применения манифеста.

Git — единственный источник истины, и kubectl apply мимо него ломает всю конструкцию. Через минуту контроллер увидит расхождение и либо откатит ручную правку (если включено самовосстановление), либо оставит её висеть как OutOfSync. Второй вариант хуже: изменение работает, но нигде не записано, и следующий, кто откроет репозиторий, увидит другую реальность. Правки мышкой в проде я разбираю как операционный инцидент с постмортемом, а не как «срочно поправил».

Откат делается через git revert, а не руками. kubectl edit в инциденте живёт ровно до следующей синхронизации: контроллер вернёт то, что лежит в git, и дежурный поймает ту же аварию второй раз, уже не понимая почему. Revert в виде PR откатывает изменение целиком и оставляет запись в журнале аудита — это и есть весь механизм отката, другого в GitOps нет.

Секреты не лежат в git в открытом виде даже в приватном репозитории. Base64 — не шифрование. «Оно же закодировано» — самая частая отговорка, которую я слышу, а по факту любой, у кого есть доступ на чтение, читает секрет как обычный текст, и ротировать после этого нужно всё, что там лежало. Sealed Secrets, External Secrets Operator и SOPS закрывают дыру, оставаясь внутри процесса PR.

Код приложения и желаемое состояние лучше держать в разных репозиториях или хотя бы разводить окружения. Когда всё в одном месте и поток PR единый, изменение «выкатить фичу» и изменение «поменять конфиг выкатки» перемешиваются, и откатить только второе уже нельзя. Рабочая схема простая: CI собирает образ, бот обновляет тег в репозитории конфигурации, Argo CD или Flux подтягивают его оттуда. Зрелые команды я отличаю ровно по этому признаку; те, у кого один репозиторий на всё, рано или поздно упираются в смешанные откаты.

Обнаружение дрейфа настроено почти у всех. Смотрит на него почти никто. Контроллер честно показывает статус, но сама по себе панель бесполезна: расхождение живёт неделями и всплывает уже инцидентом, когда кто-то наконец спрашивает, почему в кластере не то, что в репозитории. Алерт на приложение, которое висит не в Synced дольше N минут, превращает наблюдение в сигнал.

Сам GitOps тоже описывается в git. Если Argo CD или Flux ставили руками через kubectl, а конфигурация контроллера нигде не зафиксирована, то при потере кластера восстанавливать придётся по памяти — в тот единственный момент, когда памяти доверять нельзя. Лечится схемой app-of-apps: контроллер управляет сам собой через собственный Application, и подъём сводится к одной команде. Откладывают это постоянно. До первых учений по восстановлению.

Постепенную выкатку имеет смысл встраивать в тот же поток, а не рядом с ним. По умолчанию изменение едет целиком, без канарейки; Argo Rollouts с Argo CD или Flagger с Flux добавляют канареечный выкат, проверку здоровья и автоматический откат, оставляя продвижение в виде PR. Команды, у которых постепенная выкатка живёт отдельно от git, я вижу регулярно, и заканчивается это одинаково — два механизма выкатки и хрупкая склейка между ними.

Граница практики проходит по тому, декларативна ли сама система. Kubernetes сведением состояния занимается по своей природе, поэтому GitOps ложится на него без зазора. Всё, что живёт вне такой модели — миграции базы, разовые скрипты, ручные операции у поставщика, — в эту схему не помещается, и попытка затащить их туда даёт бутафорию: в репозитории лежит YAML, а изменения всё равно делаются руками. Для таких кусков честнее конвейер с шагом и журналом, чем контроллер, которому нечего сводить.

  • Infrastructure as Code — там код описывает инфраструктуру, здесь git плюс непрерывное сведение. Одно работает без другого, на практике идут вместе.
  • Progressive Delivery — canary, blue-green, feature flags. Argo Rollouts (с Argo CD) и Flagger (с Flux) — основные инструменты, которые работают внутри самого потока git.
  • Secrets Management — секреты в этом потоке: никогда открытым текстом, всегда через Sealed Secrets, External Secrets или SOPS.
  • Service Ownership — каталог сервиса содержит ссылку на его Application и репозиторий; владелец отвечает за поток PR.
  • Architecture Decision Records — выбор инструмента (Argo CD или Flux), структуры репозиториев и схемы работы с секретами — типичные темы для ADR.
  • Incident Response — аварийный откат через git revert и синхронизацию — штатный способ гашения.
  • Containerization & Orchestration — Kubernetes — основная среда для GitOps; Argo CD и Flux синхронизируют git с состоянием кластера.
  • App of Apps Pattern (TBD) — подтема Argo CD: один корневой Application управляет остальными; чем это отличается от ApplicationSet и что чем оплачивается.
  • GitOps на много кластеров (TBD) — «центр — спицы», раздача по целям, федерация; актуально примерно от пяти кластеров.
  • Policy as Code в GitOps (TBD) — Kyverno, OPA, плагины Argo CD; соседняя практика, здесь она упомянута, а отдельным листом ещё не написана.
  • Политика реакции на дрейф — самовосстановление, ручная синхронизация или только алерт; у каждого варианта своя цена. Автоматическое восстановление прячет причину в момент инцидента, ручное — тормозит возврат сервиса.