← Back to notes

GitOps — автоматизация
инфраструктуры через Git

2025-10-28


Что такое GitOps

GitOps — operating model для декларативной инфраструктуры и приложений, где Git хранит desired state, а controller/agent приводит runtime-систему к этому состоянию.

OpenGitOps (CNCF) формулирует четыре принципа (v1.0.0):

ПринципОпределение
DeclarativeСистема, управляемая через GitOps, описывает desired state декларативно.
Versioned and ImmutableDesired state хранится с гарантией immutability, версионирования и полной истории версий.
Pulled AutomaticallySoftware agents автоматически pull'ят декларации desired state из источника.
Continuously ReconciledSoftware agents непрерывно наблюдают actual state и стремятся привести систему к desired state.

source: opengitops.dev/

Ключевой нюанс формулировки: canonical-принципы говорят про pull (агент сам забирает состояние), а не push из CI. «Versioned and Immutable» шире, чем «только Git»: важна неизменяемость и история версий, хотя на практике источником почти всегда является Git.

Как работает GitOps

  1. Декларативное описание инфраструктуры
    Kubernetes manifests, Helm/Kustomize или Terraform/OpenTofu configs описывают desired state.

  2. Git как источник истины
    Репозиторий содержит версионированное состояние. Изменение — commit + review + merge.

  3. Reconciliation loop GitOps-controller (Argo CD, Flux) сравнивает live state с Git и применяет diff вручную или автоматически, в зависимости от policy.

  4. Аудит и откат изменений
    История Git даёт audit trail. Rollback обычно делается через git revert, чтобы source of truth тоже изменился.


Pull vs push и reconciliation

Push-модель (классический CI/CD): pipeline снаружи держит credentials кластера и делает kubectl apply / helm upgrade. Pull-модель (GitOps по OpenGitOps): агент внутри кластера сам pull'ит desired state и применяет его — принцип «Pulled Automatically». Плюсы pull: credentials кластера не покидают его периметр, а reconciliation идёт непрерывно, а не только в момент запуска pipeline.

source: opengitops.dev/

Reconciliation loop — периодическое сравнение desired (Git) и actual (cluster) состояний. Argo CD по умолчанию поллит Git каждые ~3 минуты; webhooks убирают задержку. Drift — расхождение actual и desired (обычно ручной kubectl edit). Реакция зависит от policy: только отметить OutOfSync либо авто-починить (selfHeal в Argo CD / непрерывное применение в Flux). Пассивный drift detection есть всегда; авто-исправление — опция.


Инструменты

ИнструментКраткое описание
Argo CDGitOps-контроллер для Kubernetes: manual/auto sync, health/status, RBAC, Web UI, ApplicationSet.
FluxCNCF GitOps toolkit для Kubernetes: source-controller, kustomize-controller, helm-controller, image automation.
FleetGitOps для мультикластерного управления Kubernetes. Подходит для масштабных инфраструктур.

Flux: набор контроллеров

Flux — не монолит, а набор специализированных контроллеров (GitOps Toolkit):

ControllerРоль
source-controllerЗабирает артефакты из источников: Git, OCI-registry, Helm-repo, S3-бакеты
kustomize-controllerПрименяет манифесты через Kustomization; умеет SOPS-decryption
helm-controllerРазворачивает Helm-чарты через HelmRelease
notification-controllerAlerts/события: Providers, Alerts, Receivers (входящие webhooks)
image-reflector-controllerСканирует registry и отслеживает доступные теги образов
image-automation-controllerКоммитит обновлённые теги обратно в Git по политикам

source: fluxcd.io/flux/components/

Автообновление образов в Flux — тремя CR: ImageRepository (скан registry), ImagePolicy (выбор тега: semver / alphabetical / numerical), ImageUpdateAutomation (коммит нового тега в Git). Место подстановки помечается в манифесте маркером # {"$imagepolicy": "flux-system:podinfo"}. То есть Flux пишет обновление обратно в Git «из коробки» — в отличие от Argo CD, которому нужен отдельный Image Updater.

source: fluxcd.io/flux/guides/image-update/


Flux vs Argo CD

Оба — CNCF-проекты, pull-based, с непрерывным reconciliation. Различия:

АспектArgo CDFlux
ФормаМонолитный контроллер + CRD ApplicationНабор контроллеров + CRD (Kustomization/HelmRelease/…)
UIВстроенный Web UI и CLICLI-first, без официального Web UI (сторонние дашборды)
Multi-tenant шаблоныApplicationSet (list/cluster/git/matrix/…)Kustomization + слои репозиториев
Автообновление образовОтдельный Argo CD Image UpdaterВстроено (image-reflector + image-automation)
СекретыЧерез сторонние решенияВстроенная SOPS-decryption в kustomize-controller
Progressive deliveryArgo RolloutsFlagger

Flagger — «Progressive Delivery Operator for Kubernetes» (canary, A/B, blue-green), часть Flux-family с 2020 (CNCF).

source: flagger.app/

Замечание: сравнение по фактам из официальной документации обоих проектов; часть пунктов (например «нет официального Web UI у Flux») — характеристика на момент написания, детали смотрите в docs.


Преимущества

  • Audit trail: кто изменил desired state и через какой review.
  • Воспроизводимость: окружение можно пересобрать из Git + артефактов.
  • Drift detection: controller видит расхождение live state и Git.
  • Откат: git revert возвращает desired state, controller применяет его.

Ограничения

  • GitOps не чинит broken desired state: плохой commit будет воспроизведён так же стабильно, как хороший.
  • Auto-sync без policy gates может быстро распространить ошибку.
  • Secrets нельзя хранить plaintext в Git; нужны SOPS, Sealed Secrets, External Secrets или Vault-интеграция.
  • Для Terraform-style инфраструктуры нужен отдельный controller/workflow, потому что Kubernetes GitOps-controller сам по себе не управляет cloud API без CRD/operator слоя.
  • Ручные изменения через kubectl создают drift и могут быть перезаписаны controller'ом.

Секреты в GitOps

Plaintext-секреты в Git недопустимы — Git хранит полную историю, откуда секрет уже не «вычистить». Основные паттерны:

ПодходИдея
SOPSШифрование data/stringData полей Secret через OpenPGP, AWS/GCP KMS, Azure Key Vault; в репозиторий попадает уже зашифрованный манифест
Sealed SecretsCRD SealedSecret + контроллер в кластере расшифровывает в обычный Secret
External Secrets Operator (ESO)Секрет живёт во внешнем store (Vault, AWS Secrets Manager, …), в Git — только ссылка

Flux поддерживает SOPS нативно: kustomize-controller при decryption.provider: sops расшифровывает Secret'ы перед применением, ключи берёт из указанного secretRef. Шифруются только поля data/stringData — не metadata/kind/apiVersion.

source: fluxcd.io/flux/guides/mozilla-sops/

Итог: в Git лежит либо зашифрованный секрет (SOPS/Sealed Secrets), либо ссылка на внешний store (ESO/Vault) — но не открытый секрет.


Практический baseline

  • Pin образов по digest или immutable tag, не latest.
  • Разделяй app repo и environment/config repo, если нужен controlled promotion.
  • Включай diff/health checks перед auto-sync.
  • Для prod — policy checks до merge: schema validation, kubeconform, OPA/Kyverno, secret scanning.
  • Rollback runbook должен начинаться с git revert; прямой rollback в controller — аварийная операция.

Ссылки

GitOps — автоматизация инфраструктуры через Git | Aleksandr Suprun