KubernetesCIII · GitOps IntroductionGitOps
Reconciliation controllers — Argo CD and Flux in depth
What you'll learn
- Use Argo CD for GitOps reconciliation
- Use Flux for GitOps reconciliation
- Choose between Argo CD and Flux
- Apply the operational discipline of treating the controller as production infrastructure
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
Argo CD and Flux are the two main GitOps controllers for Kubernetes. This lesson walks Argo CD’s architecture, Flux’s architecture, the comparison, and the operational discipline.
Argo CD architecture
flowchart LR
A[Git repository] --> B[Argo CD controller]
B --> C[Application CR]
C --> D[cluster]
B --> E[Application controller]
E -->|sync| D
B --> F[Repo server]
F -->|fetch manifests| A
B --> G[Web UI]
G --> H[User]
Argo CD components:
- Application CR — declarative definition of an app to sync (source repo + path + destination cluster + namespace).
- Application controller — reconciles actual state toward desired; syncs the cluster.
- Repo server — fetches manifests from Git; renders Helm/Kustomize.
- Web UI — the Argo CD dashboard.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: billing
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/example/manifests
targetRevision: main
path: apps/billing/overlays/prod
destination:
server: https://kubernetes.default.svc
namespace: prod-app
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
The Application CR declares what to sync, from where,
to where. syncPolicy.automated enables auto-sync;
prune deletes resources not in Git; selfHeal
corrects drift.
Flux architecture
flowchart LR
A[Git repository] --> B[Source Controller]
B --> C[GitRepository CR]
C --> D[Kustomization CR]
D -->|apply| E[cluster]
D --> F[HelmRelease CR]
F -->|install| G[Helm chart]
B --> H[Helm Controller]
Flux components:
- Source Controller — watches GitRepository CRs and fetches the source.
- Kustomize Controller — applies Kustomize overlays.
- Helm Controller — manages Helm releases.
- GitRepository, Kustomization, HelmRelease — the Flux CRDs.
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: manifests
namespace: flux-system
spec:
interval: 1m
url: https://github.com/example/manifests
ref:
branch: main
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: billing
namespace: flux-system
spec:
interval: 5m
sourceRef:
kind: GitRepository
name: manifests
path: ./apps/billing/overlays/prod
prune: true
wait: true
Flux uses CRDs per concept (source, kustomization, helm release). The pattern is more Kubernetes-native than Argo CD’s single Application CR.
The comparison
flowchart LR
A[Argo CD] --> A1[Single Application CR]
A --> A2[Web UI built in]
A --> A3["Sync waves, App of Apps"]
A --> A4["Supports Helm, Kustomize, raw YAML"]
B[Flux] --> B1["Multiple CRDs (GitRepository, Kustomization, HelmRelease)"]
B --> B2["No web UI by default (use Weave GitOps or other)"]
B --> B3[More Kubernetes-native]
B --> B4["Supports Helm, Kustomize, raw YAML"]
The trade-offs:
| Feature | Argo CD | Flux |
|---|---|---|
| Web UI | built in | requires add-on |
| CRDs | one (Application) | many (GitRepository, Kustomization, HelmRelease) |
| Sync waves | yes (annotation) | yes (dependsOn) |
| Multi-cluster | yes (Application per cluster) | yes (Kustomization per cluster) |
| Maturity | CNCF Graduated | CNCF Graduated |
| Community | larger | smaller but growing |
The choice depends on team preference. Both are production-ready.
App of Apps (Argo CD)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: prod-apps
namespace: argocd
spec:
source:
repoURL: https://github.com/example/manifests
path: clusters/prod
destination:
server: https://kubernetes.default.svc
project: default
The App of Apps pattern: a parent Application that points to a directory containing child Applications. The parent syncs the children; each child syncs its app. The pattern allows grouping apps into logical sets.
Quiz
Knowledge check · 4 questions
Q1. Where does the `argocd.argoproj.io/sync-wave` annotation belong?
Q2. Argo CD waits for every resource in a sync wave to become healthy before starting the next wave.
Q3. Work out why merged commits have stopped reaching a Flux-managed cluster and restore reconciliation.
Three commits merged to `main` three hours ago are absent from the `prod-app` namespace. `flux get kustomizations` shows `billing` Ready True with `Last Applied Revision: main@sha1:9c1f2ab`, which is yesterday's commit. `flux get sources git` shows `manifests` Ready False with `failed to checkout and determine revision: unable to clone: authentication required`.
Q4. In Flux, which controller fetches repository contents, which one applies them, and what does a Kustomization's `sourceRef` name?
Passing score: 75%. Answers are checked in this browser.
The operational discipline
The reconciliation controller in production rests on five non-negotiable elements:
- HA controller. The GitOps controller is
critical; deploy with HA (Argo CD’s
ha: trueinstall option; Flux’s HA topology). - Monitor sync status. Alert on sync failures, drift, and stale syncs.
- Test controller upgrades. Controller upgrades can break Applications; test in staging.
- Backup controller state. The controller’s state (Application CRs, Kustomization CRs) must be backed up.
- Document the topology. The Application / Kustomization hierarchy must be in the runbook.
The controller is production infrastructure. Treat it as such.