Migration and Production Patterns

Moving to Flux v2 from Flux v1, the Helm Operator, or an imperative CI pipeline — then the operational patterns that keep Flux healthy at hundreds of clusters: sharding, concurrency tuning, webhooks, self-upgrade, and disaster recovery.

Overview

Getting there, and growing

Two things separate a team that has read about Flux from a team that runs it: how they got there, and what they changed once the estate got large. Both come up in interviews because both are where the real decisions live.

Three migration paths into Flux v2

  • Flux v1 — An architecture change — Daemon flags and workload annotations become custom resources; garbage collection stops needing cluster-wide discovery access; applies become atomic after server-side validation, so latent invalid manifests surface on day one
  • Helm Operator — Narrower but fiddlier — API group moves to helm.toolkit.fluxcd.io/v2; inline chart splits into a separate HelmRepository or GitRepository source; values sources change shape and lose cross-namespace references; rollback becomes structured install and upgrade remediation
  • Imperative CI pipeline — The most common case, and not really a tooling migration — A change in who holds cluster credentials

The honest Argo CD answer

There is no automated converter.

  • Application — Kustomization or HelmRelease
  • Sync waves — spec.dependsOn
  • Projects — Namespaces plus RBAC
  • ApplicationSet — Does not map cleanly
  • UI — Not in Flux core

> [!TIP] Saying that plainly reads as judgment; claiming full parity reads as a sales pitch.

Scaling levers, in order

  • Vertical — Raise --concurrent, raise CPU and memory limits, run kustomize builds on a tmpfs /tmp, cache Helm indexes, give source-controller a PVC so artifacts survive restarts
  • Horizontal — Each instance owns a labeled subset; the main instances exclude sharded resources with a negated selector
  • Latency — Intervals long enough not to hammer Git and the API server; Receivers for responsiveness

Flux manages itself

Upgrading Flux is a commit like any other, and customizing Flux is a Kustomize patch like any other.

> [!WARNING] A bad patch to gotk-components.yaml is applied by the very controllers it breaks.

Disaster recovery

If cluster state is entirely in Git, rebuilding is flux bootstrap against the same repository.

  • Controllers, sources, Kustomizations, HelmReleases — Secrets
  • PVC declarations — Persistent volume data

> [!IMPORTANT] An interviewer asking about DR is usually checking whether you know that boundary.

Key concepts

Annotation model to CRD model
Flux v1 configured behaviour with daemon flags and per-workload annotations such as fluxcd.io/automated and fluxcd.io/ignore. Flux v2 configures everything with custom resources. The direct equivalent of fluxcd.io/ignore is the kustomize.toolkit.fluxcd.io/reconcile: disabled annotation, and the equivalent of downscaling the v1 daemon to pause is spec.suspend on a single object.
Atomic server-side validated apply
Flux v2 applies a Kustomization only if server-side validation of the whole set passes. One invalid manifest blocks every resource in that Kustomization. Flux v1 applied what it could. This is the most common surprise during a v1 to v2 migration and it is a correctness improvement, not a regression.
HelmRelease v1 to v2
helm.fluxcd.io/v1 becomes helm.toolkit.fluxcd.io/v2. The inline spec.chart.repository/name/version splits into a HelmRepository source plus spec.chart.spec.sourceRef. valuesFrom entries become kind plus name plus valuesKey with no cross-namespace references. Helm v2, downloader plugins, and external URL values are removed.
--watch-label-selector
The sharding flag. A shard runs with --watch-label-selector=sharding.fluxcd.io/key=shard1 and the main instance with --watch-label-selector=!sharding.fluxcd.io/key so the two sets are disjoint. Supported by source-controller, kustomize-controller and helm-controller; notification-controller does not shard.
--concurrent
Number of reconciliations a controller runs in parallel. The documented high-scale tuning raises it to 10 on kustomize-controller, helm-controller and source-controller, paired with container limits around 2000m CPU and 2Gi memory. This is the first lever to pull, before sharding.
--requeue-dependency
How often a controller re-checks whether the dependencies named in spec.dependsOn have become ready. The tuned reference value is 5s. Too high and dependency chains deploy slowly; too low and a deadlocked chain generates constant API traffic for nothing.
Receiver
notification.toolkit.fluxcd.io/v1 resource that creates an inbound webhook endpoint on notification-controller (port 9292 behind the webhook-receiver Service). An HMAC token in a Secret authenticates the payload, and a matching event triggers immediate reconciliation of the listed resources instead of waiting for the interval.
flux-system Kustomization
The self-referential loop created by bootstrap. gotk-components.yaml holds the controller Deployments and gotk-sync.yaml holds the GitRepository and Kustomization that reconcile them. Upgrading Flux means committing a new gotk-components.yaml; customising Flux means adding a Kustomize patch alongside it.

When to use it

  • Planning a move off archived Flux Legacy or the archived Helm Operator, where there is no upstream support and no path back
  • Replacing a CI pipeline that holds long-lived cluster credentials — the security case for pull-based delivery is usually stronger than the workflow case
  • An estate that has outgrown a single controller instance: hundreds of Kustomizations, large monorepos, or reconcile queues that never drain
  • Multi-tenant platforms that need blast-radius isolation between teams at the controller level, not just at the namespace level
  • Designing cluster disaster recovery, where the question is what reconciles back from Git and what does not
  • Evaluating Flux against Argo CD when non-platform stakeholders need self-service visibility into sync status

Interview questions

  • Walk me through migrating a team from Flux v1 to Flux v2. What has no direct equivalent?
  • How do you migrate a CI pipeline that runs helm upgrade --install to Flux, without an outage?
  • An estate has 400 Kustomizations across 60 clusters and reconciles are falling behind. How do you scale Flux?
  • How does Flux manage and upgrade itself, and what can go wrong with that?
  • A cluster is gone. How do you rebuild it with Flux, and what does not come back?
  • Give me an honest comparison of moving between Argo CD and Flux, and what Flux does not have.

Sign up free to read the full topic

More DevOps topics

Start free on Cariara · Coding problems · System design studio