Flux v2
CNCF Graduated GitOps tool. Originated at Weaveworks (the GitOps coiners). v2 rewrite from monolithic v1 to modular controllers (GOTK). Multi-tenant via K8s namespaces. Used at Mercedes-Benz, BMW, RingCentral, MOIA. Kustomize-first; tighter K8s-native than Argo CD.
Overview
Flux v2 and the GitOps Toolkit
Flux v2 is the K8s-native GitOps tool from Weaveworks, which coined the term GitOps in 2017. v1 was the original implementation; v2 (released 2021) is a complete rewrite into the GitOps Toolkit (GOTK), a set of composable Kubernetes controllers. It graduated in the CNCF in November 2022, the same month as Argo CD.
Why Flux wins
- K8s-native idioms — Every concept is a CRD (GitRepository, Kustomization, HelmRelease, Receiver, Provider, ImageUpdateAutomation); RBAC, namespaces, finalizers and status conditions apply uniformly; kubectl get/describe work on everything
- Multi-tenancy via namespaces — A tenant's GitRepository + Kustomization + HelmRelease live in its namespace, isolated by K8s RBAC; cleaner than Argo CD's bolted-on AppProjects
- Composable — Thin controllers: install kustomize-controller without helm-controller, or just source + image automation, or write a custom controller consuming source-controller artifacts
- flux CLI — Bootstrapping, manifest generation, reconciling, debugging; flux bootstrap installs Flux and configures it to manage its own configuration via GitOps
- CNCF ecosystem — Used at Mercedes-Benz, BMW, RingCentral, MOIA, MyFitnessPal; featured in CNCF case studies
Where Flux has friction
- Thinner UI — Weave GitOps OSS exists but is less polished; most work happens via flux CLI / kubectl, so UI-driven app teams often prefer Argo CD
- No single deployment unit — You compose GitRepository + Kustomization (or HelmRelease): more moving parts, more YAML
- Per-controller sharding — Argo CD's application-controller scales as one; Flux's controllers scale independently: more flexibility, more configuration
When to pick which
- K8s-native composability: teams comfortable operating controllers, wanting CRD-first patterns and custom extensions — Application teams need a polished UI for sync status, troubleshooting, drift visualization
- Namespace multi-tenancy with RBAC isolation — A centralized control plane for many clusters: Argo CD's hub-and-spoke is more mature
- Already on Flux v1: migrating to v2 is more incremental — Argo Rollouts integration: tighter coupling
- Built-in image automation via ImageUpdateAutomation (Argo CD needs the separate Image Updater)
Three load-bearing concepts
- GOTK is composable — source, kustomize, helm, notification and image-automation controllers are independent; pick what you need
- Two-step reconciliation — source-controller fetches; kustomize-controller (or helm-controller) applies. Unlike Argo CD's monolithic application-controller
- Namespace + RBAC multi-tenancy — Tenant CRDs in the tenant namespace; standard K8s primitives enforce isolation
Key concepts
- GitRepository — source CRD
- Tells source-controller where to pull manifests from. source-controller fetches at interval; produces an Artifact (in-cluster tarball with checksum). Other controllers consume the Artifact. ref options: branch (mutable; usually main), tag (immutable), semver (range), commit (specific SHA — most reproducible for production). Pin production GitRepository to specific commit or tag, not branch — avoids picking up unintended changes. ignore: gitignore-style filter to exclude paths from the artifact. Reduces artifact size; speeds up downstream rendering. Other source kinds: - HelmRepository — chart repository (https or OCI). - Bucket — S3, GCS, MinIO. - OCIRepository — OCI artifacts (manifests stored in container registry).
- Kustomization — apply manifests
- kustomize-controller applies Kustomize-rendered manifests to the cluster. prune: true removes resources removed from git (Argo CD equivalent: prune: true in syncPolicy). wait: true blocks reconciliation until the applied resources are Ready (Deployment Available, etc.). Useful for ordering dependent Kustomizations via dependsOn. serviceAccountName: impersonate this ServiceAccount when applying. Used for multi-tenancy: tenant Kustomization runs as tenant ServiceAccount; RBAC restricts what it can apply. postBuild.substitute: variable substitution using ${var} placeholders in the rendered output. Useful for cluster-specific values (region, environment) without per-cluster overlays. healthChecks: explicit health check beyond what wait: true does. Useful for resources with custom health logic. Multiple Kustomizations can chain via dependsOn: Reconciles only after the named Kustomizations are Ready.
- HelmRelease — Helm chart deployment
- helm-controller applies Helm releases. helm-controller renders the chart with values, installs/upgrades the release, tracks Helm history. Auto-rollback on failure via upgrade.remediation.strategy: rollback. Helm reverts to previous release if upgrade fails health checks. Multiple HelmReleases can chain via dependsOn (same as Kustomization). Compared to ArgoCD's Helm support: Flux's HelmRelease is closer to native Helm semantics (uses helm install/upgrade under the hood); ArgoCD's Helm renders manifests and applies via kubectl. Different reconciliation models; both work.
- Multi-tenancy via namespaces
- Flux's multi-tenancy story is namespace-native. Tenant CRDs in tenant namespace; K8s RBAC enforces isolation. Setup for tenant payments-team: 1. Namespace per tenant: 2. Tenant ServiceAccount with restricted permissions: 3. Tenant team owns GitRepository + Kustomization in their namespace: Behavior: kustomize-controller impersonates payments-deployer SA when applying. SA only has edit on payments-prod namespace. Tenant cannot deploy to other namespaces, cannot create ClusterRoles, cannot escape their scope. Compared to Argo CD AppProject: similar isolation, different mechanism. Flux uses K8s-native impersonation; Argo CD uses AppProject scope checks. Flux's approach is more idiomatic; Argo CD's allows centralized governance more easily.
- Notification controller — Slack/Webhook events
- notification-controller is bidirectional: receives webhooks, sends events. Receiver — incoming webhook to trigger reconciliation: Receiver creates a Service exposing /hook/. GitHub webhook hits it; Receiver triggers immediate reconciliation of listed resources. Reduces lag from minutes to seconds. Provider + Alert — outgoing events: Behavior: every Kustomization reconciliation produces an event; Alert filters by severity/source/regex; matching events forwarded to Slack via Provider. Provider types: slack, discord, msteams, rocket, generic, github, gitlab (commit status), webex, sentry, pagerduty, alertmanager. GitHub commit status integration: post sync results back to the commit on GitHub. Adds context to PRs ("deploy to prod-eu-west-1: succeeded").
- Recipe: flux bootstrap on EKS with multi-cluster
- flux bootstrap installs Flux on a cluster and configures it to manage its own config via GitOps. Step 1 — bootstrap on hub cluster: What this does: - Creates github.com/myorg/gitops-fleet (if missing). - Generates flux-system manifests in clusters/prod-hub/flux-system/. - Commits + pushes to git. - Installs Flux on the cluster. - Configures Flux to reconcile clusters/prod-hub/. After bootstrap, Flux's own manifests live in git. Self-managed. Upgrades happen by editing the gotk-components.yaml in git and pushing. Step 2 — define spoke cluster Kustomizations: Step 3 — bootstrap each spoke cluster: Each spoke runs its own Flux installation. Federated topology — each cluster manages itself from git. No central control plane. Compared to Argo CD hub-and-spoke: Flux federated approach has lower blast radius (hub failure doesn't affect spokes) but higher operational surface (5 clusters = 5 Flux installations). Step 4 — image automation (Flux's killer feature): Setters strategy: in your manifests, mark fields with a comment: Behavior: image-reflector-controller scans GHCR every 5 min; new tag matching semver range → image-automation-controller commits the updated image tag to git → source-controller picks up commit → kustomize-controller applies. Fully GitOps-managed image updates with audit trail (the auto-commit is in git history).
When to use it
- K8s-native composability matters; want CRD-first patterns
- Multi-tenant clusters where namespace-based isolation is desired
- Already on Flux v1 — migration to Flux v2 is incremental
- GitOps-managed image automation via ImageUpdateAutomation
- Platform team comfortable extending K8s controllers with custom CRDs
Interview questions
- Walk through Flux v2 GOTK architecture — five controllers, each role.
- How does Flux's multi-tenancy compare to Argo CD AppProjects?
- How does Flux handle image automation (the GitOps for container images)?
- Federated vs hub-and-spoke — when does each fit?
- Quick-fire interview answers — Flux essentials.
Sign up free to read the full topic
More DevOps topics
Start free on Cariara · Coding problems · System design studio