Skip to content

GitOps — Basics

Git is the single source of truth for infrastructure and app state. A controller continuously reconciles the cluster to match git.

  1. Declarative — system state expressed declaratively.
  2. Versioned + immutable — git commits.
  3. Pulled automatically — agents reconcile, not external pushers.
  4. Continuously reconciled — agents detect and correct drift.
  • Auditable — every change is a commit.
  • Reversible — git revert and reconcile.
  • Disaster recovery — re-create cluster from git.
  • Reduces secret sprawl in CI runners (CI has no cluster creds; cluster pulls).
  • Drift detection.
  • Argo CD — most popular. Polls git → applies to cluster. Web UI shows diff.
  • Flux — CNCF graduated. CLI/CRDs. Works with Helm + Kustomize.
  • Jenkins X, Rancher Fleet — alternatives.
  • Simple. Coupled.
  • App repo CI builds image, opens PR to manifests repo with new tag.
  • Manifests repo is canonical “what’s running where”.
  • One root app references many child apps. Add new service = new entry.
clusters/
prod/
apps/api.yaml
apps/web.yaml
infra/cert-manager.yaml
staging/
manifests/
base/api/{deployment,service,ingress}.yaml
overlays/staging/api/kustomization.yaml # env-specific patch
overlays/prod/api/kustomization.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata: { name: api, namespace: argocd }
spec:
project: default
source:
repoURL: https://github.com/org/manifests
path: overlays/prod/api
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: app
syncPolicy:
automated: { prune: true, selfHeal: true }
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata: { name: api, namespace: flux-system }
spec:
interval: 1m
path: ./overlays/prod/api
prune: true
sourceRef: { kind: GitRepository, name: manifests }

Image bumps via tools that watch a registry:

  • Argo CD Image Updater — patches manifest with new image tag.
  • Flux Image Automation — same idea, native to Flux.
  • Renovate — opens PRs for image updates.

Pattern: CI pushes image with sha tag → image updater bumps tag in manifests → controller deploys.

You can’t commit raw secrets. Solutions:

  • Sealed Secrets (Bitnami) — encrypt with cluster’s pubkey, decrypt in cluster.
  • SOPS + age/PGP — files encrypted in git; decrypted by Flux/Argo plugin.
  • External Secrets Operator — fetch from Vault/Secrets Manager at runtime; only refs in git.
  • Argo CD shows OutOfSync state.
  • selfHeal: true re-applies; rejects manual edits.
  • Use carefully — may fight legitimate ops scripts; better to disable selfHeal during incident response (kubectl annotate ... disable-sync).

Often via PRs:

dev → manifests/dev/api auto-bumped on every CI pass
staging → manifests/staging/api bumped on dev success (PR)
prod → manifests/prod/api bumped manually (PR review)

Tooling: kargo, kosli, Argo CD ApplicationSets per env, custom scripts.

  • Bypassing git (kubectl edit prod) — breaks audit + drift detection.
  • Storing secrets in plain in repo.
  • Single repo for all envs without protection rules — accidental prod merge.
  • Auto-sync prod without PR review.
  • Long-lived branches diverging from main.
  • Image tag = latest in manifests.
  • Argo CD, Flux v2.
  • Argo Rollouts — canary/blue-green built into manifests.
  • Kustomize, Helm.
  • kargo — Argo CD promotion engine.
  • External Secrets Operator.
  • Sealed Secrets, SOPS.
  • PR-driven automation: bot-managed branches/PRs.