Что такое GitOps
GitOps — operating model для декларативной инфраструктуры и приложений, где Git хранит desired state, а controller/agent приводит runtime-систему к этому состоянию.
OpenGitOps (CNCF) формулирует четыре принципа (v1.0.0):
| Принцип | Определение |
|---|---|
| Declarative | Система, управляемая через GitOps, описывает desired state декларативно. |
| Versioned and Immutable | Desired state хранится с гарантией immutability, версионирования и полной истории версий. |
| Pulled Automatically | Software agents автоматически pull'ят декларации desired state из источника. |
| Continuously Reconciled | Software agents непрерывно наблюдают actual state и стремятся привести систему к desired state. |
Ключевой нюанс формулировки: canonical-принципы говорят про pull (агент сам забирает состояние), а не push из CI. «Versioned and Immutable» шире, чем «только Git»: важна неизменяемость и история версий, хотя на практике источником почти всегда является Git.
Как работает GitOps
-
Декларативное описание инфраструктуры
Kubernetes manifests, Helm/Kustomize или Terraform/OpenTofu configs описывают desired state. -
Git как источник истины
Репозиторий содержит версионированное состояние. Изменение — commit + review + merge. -
Reconciliation loop GitOps-controller (Argo CD, Flux) сравнивает live state с Git и применяет diff вручную или автоматически, в зависимости от policy.
-
Аудит и откат изменений
История 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.
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 CD | GitOps-контроллер для Kubernetes: manual/auto sync, health/status, RBAC, Web UI, ApplicationSet. |
| Flux | CNCF GitOps toolkit для Kubernetes: source-controller, kustomize-controller, helm-controller, image automation. |
| Fleet | GitOps для мультикластерного управления Kubernetes. Подходит для масштабных инфраструктур. |
Flux: набор контроллеров
Flux — не монолит, а набор специализированных контроллеров (GitOps Toolkit):
| Controller | Роль |
|---|---|
| source-controller | Забирает артефакты из источников: Git, OCI-registry, Helm-repo, S3-бакеты |
| kustomize-controller | Применяет манифесты через Kustomization; умеет SOPS-decryption |
| helm-controller | Разворачивает Helm-чарты через HelmRelease |
| notification-controller | Alerts/события: 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 CD | Flux |
|---|---|---|
| Форма | Монолитный контроллер + CRD Application | Набор контроллеров + CRD (Kustomization/HelmRelease/…) |
| UI | Встроенный Web UI и CLI | CLI-first, без официального Web UI (сторонние дашборды) |
| Multi-tenant шаблоны | ApplicationSet (list/cluster/git/matrix/…) | Kustomization + слои репозиториев |
| Автообновление образов | Отдельный Argo CD Image Updater | Встроено (image-reflector + image-automation) |
| Секреты | Через сторонние решения | Встроенная SOPS-decryption в kustomize-controller |
| Progressive delivery | Argo Rollouts | Flagger |
Flagger — «Progressive Delivery Operator for Kubernetes» (canary, A/B, blue-green), часть Flux-family с 2020 (CNCF).
Замечание: сравнение по фактам из официальной документации обоих проектов; часть пунктов (например «нет официального 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 Secrets | CRD 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 — аварийная операция.