GitOps for Industrial Fleets: ArgoCD vs Flux Tutorial (2026)
Last Updated: October 2026
Most GitOps guides quietly assume that a cluster can reach its Git server whenever it likes, that a failed sync is an inconvenience, and that “production” is one environment. None of that survives contact with a fleet of several hundred factory, plant and substation clusters. Links drop for days. A bad rollout does not page a developer; it stops a packaging line. And an auditor will ask who approved the change that reached cell 14 on a Tuesday night. This ArgoCD Flux GitOps industrial fleets tutorial 2026 is written for the people who have to make that work: platform and OT engineers running Kubernetes at the edge.
The October 2026 picture has changed since our April version. Argo CD is on 3.5 with Helm 4 support, Flux has just shipped 2.10, and the argocd-agent project now gives Argo a genuine pull-style edge story. We will compare the two tools on the properties that matter for industrial fleets, build a working repository layout, and walk through rollout rings, offline operation, supply-chain verification and failure handling.
What this covers: the constraints that make industrial GitOps different, a decision between hub, pull and hybrid topologies, runnable ApplicationSet and Flux examples, disconnected-site patterns, and an honest list of what goes wrong.
Context and Background: Why Fleet GitOps Is Not Cloud GitOps
GitOps, as defined by the OpenGitOps principles, means the desired state is declarative, versioned and immutable, pulled automatically by software agents, and continuously reconciled. Both Argo CD and Flux are CNCF graduated projects that implement these principles for Kubernetes. In a single-region cloud estate the difference between them is mostly taste. In an industrial fleet the differences become architectural, because the network, the blast radius and the approval process all change.
Consider what is true of a typical plant cluster. It runs a lightweight distribution such as k3s (see our k3s edge Kubernetes production guide) on one to three nodes. Its uplink may be cellular, satellite or a firewalled OT-to-IT conduit that only allows outbound connections on a schedule. It hosts workloads such as MQTT bridges, OPC UA gateways, historian collectors and inference services that a production line depends on. And it sits inside a compliance regime, such as IEC 62443 or a customer’s change-control policy, that wants evidence for every change.
Three consequences follow. First, connectivity is a variable, not a constant. The system must behave correctly when a cluster has been offline for 72 hours, not merely slow. Second, the unit of risk is the site, so rollouts must be staged across sites in rings rather than applied everywhere at once. Third, the cluster must keep running its last known good state when the control plane, the Git server or the registry is gone. A GitOps tool that stops the line when its hub restarts has failed the first test.
The last two years also changed the supply-chain context. Registry rate limits, deleted free catalogues and compromised CI actions have made “pull from the public internet at deploy time” a liability. The Flux project’s own 2026 write-up of its new Flux Mirror plugin cites Docker Hub rate limiting, Broadcom’s freeze of the free Bitnami catalogue and a compromised GitHub Action as the reasons to keep clusters reconciling only from registries you operate. For fleets, that is not a nice-to-have; it is the design baseline.
Throughout this post we refer to our earlier comparison, the ArgoCD vs Flux GitOps decision record, which covers the generic trade-offs. Here we focus on the fleet-specific mechanics, and we update every version-sensitive claim for October 2026. The authoritative references are the Argo CD documentation and the Flux documentation.
The five constraints we design against
Rather than a generic checklist, we use five constraints as a scoring rubric for every decision later in the post.
Intermittent links. Every sync path must tolerate a missing upstream and resume cleanly. This rules out designs where the cluster needs a live call to a central API in order to keep reconciling.
Bounded blast radius. A change reaches one cell, then one plant, then a region. Rings must be encoded in Git and enforced by the tooling, not by a runbook.
Evidence. Each applied revision must map to a signed commit or signed artifact, a reviewer and a timestamp. Evidence must survive the loss of the hub.
Autonomy under failure. Clusters self-heal from local state. Drift correction is deliberate, because some OT environments forbid automatic reversion of operator changes.
Operational cost at N=1,000. Reconciliation load, API server pressure and per-cluster memory must be modest, because edge nodes often have 4 to 8 GB of RAM in total.
Reference Architecture: Hub, Pull and Hybrid Topologies
The direct answer: for industrial fleets, pick the topology before you pick the tool. A push-style hub (Argo CD managing remote clusters) gives the best central visibility but depends on reachability. A pull model (Flux in every cluster, or the argocd-agent) gives autonomy and survives outages. Most mature fleets end up hybrid: pull-based reconcilers at the edge and a thin central layer for policy, promotion and reporting.

Figure 1: Reference topology for an argocd flux gitops industrial fleet. Git and the registry feed a regional mirror tier; plant clusters pull from the nearest mirror and report status upward.
Figure 1 shows the structure we recommend. Authoring happens in a central Git repository, where pull requests, reviews and signature checks live. A CI pipeline builds images and packages desired state as OCI artifacts, and both are pushed to a central registry. A regional tier (one per country or per cluster of plants) mirrors images and artifacts. Plant clusters reconcile only from the nearest mirror, never from the public internet and ideally not from the central Git server either.
Topology A: Argo CD hub with remote clusters (push-style)
In the classic Argo CD model, one control plane holds cluster credentials and its application controller talks to every managed cluster’s API server. An ApplicationSet generates one Application per cluster. The benefits are real: a single UI, one RBAC model, one audit trail, and excellent diff and rollback ergonomics.
The costs show up at scale and at the edge. The controller needs a network path to each API server, which usually means inbound firewall holes or a VPN mesh (compare options in our WireGuard vs Tailscale vs NetBird edge fleet networking analysis). Cluster credentials are concentrated in one place, so the hub becomes a high-value target. And if the link to a plant is down, that plant is simply invisible and unmanageable until it returns. The sharded application controller helps with load, but it does not change the reachability model.
Hub-style Argo CD remains a good fit for sites with stable, always-on connectivity, such as data-centre clusters, large plants with redundant WAN links and test environments.
Topology B: Flux in every cluster (pull-style)
Flux inverts the model. Each cluster runs its own source-controller, kustomize-controller, helm-controller and notification-controller. The cluster fetches a Git repository or, increasingly, an OCI artifact, and reconciles locally. Nothing outside needs credentials to the cluster, and a hub outage has no effect on reconciliation. The only dependency is the source, which can be a local mirror.
This matches industrial constraints closely. Outbound-only connections suit OT firewalls. The footprint is small: Flux is a set of controllers rather than a server with a UI, a Redis cache and a repo server. And multi-tenancy is built on Kubernetes primitives, since each Kustomization can impersonate a ServiceAccount. The cost is visibility: there is no built-in fleet-wide UI, so you must aggregate status yourself, typically with Prometheus metrics from the controllers, Flux events forwarded through the notification-controller, and the Flux Operator’s tooling.
Topology C: argocd-agent, Argo’s answer to pull
The argocd-agent project (under the argoproj-labs organisation) targets exactly the gap between A and B. A central control plane keeps the familiar Argo CD UI and API. An agent in each workload cluster handles local reconciliation, and each cluster runs its own application controller. Crucially, the connection is inverted: agents open connections to a “principal” component on the control plane over gRPC with CloudEvents on mutual TLS, so the hub needs no network path into the plant and holds no cluster credentials.
It supports two modes. In managed mode, applications are defined on the control plane and distributed to agents, which suits central governance. In autonomous mode, applications are defined locally and synced back for observability, which suits air-gapped or locally governed sites. The project describes itself as in active development, and its own documentation lists known limitations, including that the principal does not yet support high availability and that multi-tenancy and advanced RBAC are still being built. Treat it as a strong option to pilot, not as a drop-in replacement for a mature pull setup. Verify current status against the project documentation before committing.
Topology D: the hybrid we actually recommend
Our April post recommended “Argo hub plus Flux edge”. That remains workable but carries a cost: two reconciler technologies, two skill sets and two failure modes. In October 2026 we would narrow the choice to two designs.
Design 1, Flux-first. Flux in every cluster, pulling from regional OCI mirrors, with a Flux Operator-based control layer for fleet promotion, plus Prometheus and Grafana for fleet health. This is the lowest-risk path for strict air-gap and bandwidth constraints.
Design 2, Argo-first with agents. Argo CD control plane with argocd-agent for edge clusters and direct management for well-connected data-centre clusters. This is attractive if your organisation already standardised on Argo CD for developer workflows and wants a single UI.
A mixed design, where Argo governs the application layer and Flux bootstraps the platform layer, is still legitimate when teams own different layers. The rule is that each object is owned by exactly one reconciler, because two controllers fighting over a resource is the most common source of mysterious drift.
How the two tools compare on fleet criteria
| Criterion | Argo CD (hub) | Argo CD + agent | Flux (per cluster) |
|---|---|---|---|
| Connection direction | Hub to cluster | Agent to hub | Cluster to source |
| Cluster credentials held centrally | Yes | No | No |
| Runs with hub or Git down | No new syncs | Local controller keeps state | Yes, from last artifact |
| Central UI | Built in | Built in | Add-on, Operator web UI |
| Per-cluster footprint | None on target | Agent plus controller | Four to six controllers |
| Maturity for edge | Mature as hub | Active development | Mature |
| Fleet templating | ApplicationSet | ApplicationSet | Kustomize overlays, Operator ResourceSets |
The table’s “footprint” row deserves a caveat: we have not published measured memory figures here, because they vary with the number of objects and the Kubernetes distribution. Measure on your own hardware with a representative object count before sizing edge nodes.
Build It: Repository Layout, Rollout Rings and Fleet Templating
A fleet repository has two jobs: describe what runs, and describe where. Mixing them is the first mistake teams make. Keep platform and application definitions (what) in one tree, and fleet membership and ring assignment (where) in another, so that moving a plant from the canary ring to the production ring is a one-line change that touches no manifests.
fleet-repo/
apps/ # what runs: Kustomize bases and Helm values
mqtt-bridge/base/
opcua-gateway/base/
historian-collector/base/
overlays/ # per-ring and per-region patches
ring0-lab/
ring1-canary/
ring2-early/
ring3-broad/
fleet/ # where it runs: one small file per cluster
plant-de-001.yaml # ring: ring1-canary, region: eu
plant-de-002.yaml
plant-us-014.yaml
policies/ # admission policies, network policies
Each file under fleet/ is a tiny record: cluster name, ring, region, a flag for connectivity class. Generators read these records. Everything else is plain Kustomize, which both tools understand.
Defining rings that the tooling enforces
A ring is a named cohort of clusters that receive a revision together. A sensible industrial default is four rings. Ring 0 is a lab or digital-twin replica of a plant. Ring 1 is one or two real but low-criticality sites. Ring 2 is roughly a tenth of the fleet across regions and hardware generations. Ring 3 is everyone else. The exact sizes are a policy decision; the principle is that every ring is a gate and that failure in one ring stops promotion.

Figure 2: Revision promotion through rollout rings. Each ring is gated on health checks and a soak period before the next ring is allowed to reconcile the new revision.
Two enforcement styles exist. In the Git-promotion style, a pipeline moves a revision pointer (a tag, a branch or an OCI tag) from ring to ring after checks pass. Clusters in each ring track their ring’s pointer. This works identically with Flux and Argo CD and is the style we prefer for fleets, because the promotion decision is itself a Git commit or registry tag that can be signed and audited. In the controller-orchestrated style, the tool sequences rollout itself. Argo CD’s ApplicationSet offers progressive syncs with a RollingSync strategy that updates applications in steps selected by labels. That feature has been maturing across 3.x releases, so check its stability level in the documentation for your exact version before relying on it for production gating.
ApplicationSet for a hub or agent topology
The following ApplicationSet reads cluster records from the fleet directory and generates one Application per plant, with the ring label controlling which overlay is used. It uses Go templating, which is preferable to the older fasttemplate syntax because it can fail loudly on missing keys.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: plant-core-services
namespace: argocd
spec:
goTemplate: true
goTemplateOptions: ["missingkey=error"]
generators:
- git:
repoURL: https://git.example.internal/fleet-repo.git
revision: main
files:
- path: "fleet/*.yaml"
template:
metadata:
name: "{{ .cluster }}-core"
labels:
ring: "{{ .ring }}"
spec:
project: plants
source:
repoURL: https://git.example.internal/fleet-repo.git
targetRevision: "{{ .ringRevision }}"
path: "overlays/{{ .ring }}"
destination:
name: "{{ .cluster }}"
namespace: plant-core
syncPolicy:
automated:
prune: false
selfHeal: false
syncOptions:
- ServerSideApply=true
Several choices here are deliberate. prune: false and selfHeal: false mean Argo CD detects drift and reports it, but does not delete resources or revert operator changes on its own. That is often what OT owners want: visibility without surprise. ServerSideApply=true avoids the annotation size limit that large CRDs hit under client-side apply. And targetRevision comes from the cluster record, so each ring tracks its own pointer.
In an argocd-agent deployment the template is conceptually the same, but the application is mapped to the agent’s namespace on the control plane and the destination is the agent’s local cluster rather than a remote API server URL. Follow the argocd-agent documentation for the mapping mode (by namespace or by destination name) that fits your tenancy model.
Sync windows and manual gates in Argo CD
Industrial sites often have maintenance windows. Argo CD’s AppProject supports syncWindows, which allow or deny automated and manual syncs on a cron schedule for matching applications, namespaces or clusters. A deny window covering a production shift keeps automated syncs away from a running line, while an allow window opens a change slot overnight. Combine that with automated sync for rings 0 to 2 and manual sync for ring 3 on safety-critical cells, and you have an approval gate that is visible in the UI and recorded in the audit trail.
For the platform layer, use sync waves (the argocd.argoproj.io/sync-wave annotation) to order CRDs before controllers before workloads. Keep waves shallow. Deep wave chains make failure diagnosis slow, and every wave waits for the previous one to be healthy.
The Flux equivalent: Kustomizations, health checks and dependencies
In Flux, the ring pointer is typically an OCI artifact tag. CI packages the overlay for a ring with flux push artifact and tags it with the revision and the ring name. The cluster tracks that tag through an OCIRepository, and a Kustomization applies it.
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: fleet-config
namespace: flux-system
spec:
interval: 10m
url: oci://registry.plant-de-001.internal/fleet/config
ref:
tag: ring1-canary
verify:
provider: cosign
matchOIDCIdentity:
- issuer: "^https://token\\.actions\\.githubusercontent\\.com$"
subject: "^https://github\\.com/example-org/fleet-repo/.*$"
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: core-services
namespace: flux-system
spec:
interval: 10m
retryInterval: 2m
timeout: 5m
sourceRef:
kind: OCIRepository
name: fleet-config
path: ./
prune: false
wait: true
dependsOn:
- name: platform-crds
postBuild:
substituteFrom:
- kind: ConfigMap
name: cluster-vars
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: mqtt-bridge
namespace: plant-core
The verify block makes the cluster refuse any artifact whose cosign signature does not match the expected CI identity, which turns “signed by our pipeline” from a policy statement into an enforced precondition. dependsOn orders platform pieces before applications. wait: true with healthChecks makes the Kustomization report Ready only when the workload is actually healthy, which is what downstream gates and notifications should key off.
Flux 2.8 added Common Expression Language (CEL) based readiness checks for Helm-managed objects and Helm v4 support in the HelmRelease controller, along with kstatus health checking and a feature gate that cancels an in-progress health check when a new revision arrives, speeding recovery from a bad release. Flux 2.10 builds on this; we cover the 2026 changes in a dedicated section below.
Fleet-wide variation without forking manifests
Cluster-specific values (site code, broker address, time zone, PLC subnet) should never be baked into manifests. In Flux, use postBuild.substituteFrom pointing at a per-cluster ConfigMap or Secret that is created at provisioning time. In Argo CD, use ApplicationSet template parameters from the fleet record, or per-cluster Helm values files selected by path. The principle is the same: the shared base is identical for the whole fleet, and the only per-site material is a small, reviewable record.
Disconnected Sites: Mirrors, Artifacts and Last-Known-Good State
When a site goes offline, three questions matter. Can the cluster keep running? Can it recover from a local restart? And what happens when connectivity returns? Good GitOps design answers all three without human intervention.

Figure 3: Disconnected-site data flow. The plant cluster reads only from local mirrors; if the upstream link is down, reconcilers keep the last applied revision and retry with backoff.
Why pull-from-Git is the wrong source for remote sites
Reconciling directly against a central Git server over a poor link has two problems. Git clones are chatty and cost bandwidth proportional to history, and the server becomes a runtime dependency of every cluster. The modern answer, which the Flux project calls moving toward “Gitless GitOps”, is to treat Git as the authoring and review system and an OCI registry as the runtime source of truth. CI renders desired state into an immutable, signed OCI artifact; clusters pull that artifact from a registry close to them. Registries are built for caching, content-addressed distribution and replication, so the edge fetches only layers it lacks.
Argo CD can also consume OCI sources, and the Source Hydrator work in the 3.x line, which moved to beta in 3.5 by the project’s documentation, pushes rendered manifests into a Git branch so that clusters apply pre-rendered output rather than rendering Helm or Kustomize at sync time. Either approach reduces the number of moving parts that must function at the edge.
Mirroring images and charts
Every image a plant cluster needs must be present in a registry that cluster can reach. A regional Harbor, Artifactory or Zot instance is the typical mirror. The mirror must copy more than image bytes: it should preserve digests, copy signatures and attestations, and ideally verify them on the way in.
Flux Mirror, announced in August 2026 as a plugin in the Flux 2.9 CLI plugin system, targets this problem. According to the project’s announcement and trade-press coverage, it copies container images (including multi-architecture manifests), republishes HTTP-based Helm charts as deterministic OCI artifacts, selects versions using regex and semver rules, verifies Cosign signatures before copying, and can hold back newly signed artifacts for a minimum age. It runs as a CI step or as a Kubernetes CronJob. General-purpose tools such as regctl, ORAS and skopeo can also copy artifacts, but you then have to build verification and drift detection around them yourself. We have not benchmarked Flux Mirror; evaluate it against your registry and artifact volume.
A practical rule: clusters pull by digest wherever possible, with the tag used only for human readability. Digest pins make a mirror transparent, because the same digest resolves to the same bytes anywhere, and they defeat tag-mutation attacks.
Containerd mirror configuration as the safety net
Even with perfectly rendered manifests, third-party charts reference images by upstream names. Configure the container runtime to redirect pulls to the mirror, so that nothing depends on manifest rewriting. On k3s this is done in registries.yaml; on other distributions it is a containerd hosts.toml entry.
# /etc/rancher/k3s/registries.yaml
mirrors:
docker.io:
endpoint:
- "https://registry.plant-de-001.internal"
ghcr.io:
endpoint:
- "https://registry.plant-de-001.internal"
registry.k8s.io:
endpoint:
- "https://registry.plant-de-001.internal"
This catches images that slip past rewriting, and it gives you a single choke point to monitor for pull failures.
What happens when the link returns
Both tools behave sensibly in principle, but the details matter. Flux reconcilers keep the last successfully fetched artifact and retry with backoff; when the source reappears, they fetch the newest revision for the tracked ref. If the ring pointer moved several times during the outage, the cluster jumps straight to the latest value rather than replaying history, which is usually what you want, though it means a site can skip an intermediate revision. If your change process requires sequential application (for example, a database schema migration chain), encode the ordering in the workload’s own migration logic, not in the delivery tool.
For Argo CD in hub mode, a returning cluster is simply reachable again and the next refresh picks up differences. With the agent, the agent reconnects to the principal and resumes. In autonomous mode, local applications continue to reconcile from locally reachable sources throughout.
Always set staleness alerts. A cluster that has not reconciled a new revision for longer than its expected window is a finding, even if it is healthy. We return to this under observability.
Sneakernet and fully air-gapped plants
Some sites have no inbound path at all. For those, package the OCI artifacts and images into an offline bundle (a tarball or an OCI layout directory) with signatures and a manifest, carry it across the boundary through your approved media process, and load it into the local registry. The cluster then reconciles from that registry exactly as before, so no special-case GitOps configuration is needed. The key is that verification still happens on the cluster: the bundle’s authenticity is established by the cosign signature, not by the transport.
Evidence, Supply Chain and What Changed in Flux 2.10 and Argo CD 3.5
Regulated plants need evidence, and evidence for a GitOps system means answering one question: why is this exact artifact running here? The strongest answer chains together a reviewed commit, a signed build, a signed artifact and a cluster that verifies signatures before applying.

Figure 4: Evidence chain for fleet deployments. Each hop adds a verifiable claim; the cluster checks signatures and admission policy before anything runs.
Signed commits and signed artifacts
Both tools can verify Git commit signatures. Argo CD supports GnuPG signature verification through the AppProject’s signatureKeys setting, and Flux’s GitRepository supports commit verification through spec.verify with a secret holding trusted keys. Signature verification at the Git layer proves who authored a revision. But since the cluster in a Gitless design pulls an OCI artifact, the more important check is the artifact signature, which Flux performs natively on OCIRepository and HelmChart sources using Cosign. For images, pair this with an admission policy that rejects unsigned images; see our write-ups on SLSA and Sigstore supply-chain architecture and Kubernetes ValidatingAdmissionPolicy with CEL.
Regulation is also catching up with software supply chains. For connected products placed on the EU market, the Cyber Resilience Act brings software bill of materials expectations; our analysis of CRA, SBOMs and firmware compliance and the SBOM and VEX triage guide explain what to attach to artifacts so the cluster-side evidence is complete.
What Flux 2.10 changes for fleets
Flux 2.10 reached general availability on 26 October 2026. The release announcement lists several items relevant to industrial operators.
SPIFFE-based inter-controller mTLS. Flux controllers can authenticate each other with X.509 SVIDs obtained from a SPIFFE Workload API such as SPIRE. Artifact fetching, internal event delivery and external webhooks can each be enabled independently. If you already run identity at the edge, see our SPIFFE and SPIRE workload identity architecture post.
Object identity, now GA. Individual Flux objects can use .spec.serviceAccountName with a ServiceAccount-based credential provider, which allows per-tenant registry and cloud access without static secrets. Note the upgrade caveat: default RBAC no longer grants create on serviceaccounts/token, so deployments using the Kubernetes credential provider must bind that permission before upgrading.
Alert and Provider APIs promoted to v1. The v1beta3 version is deprecated but still served, and the flux migrate command converts both live resources and Git manifests. Some fields are dropped in conversion, so review the migration notes before bulk changes.
Image automation and Helm refinements. A policy change delay batches image updates into one commit, and HelmRelease can reference an OCIRepository chart source inline. The image-reflector-controller now stores tags using Flux artifact storage instead of BadgerDB by default, which triggers a one-time re-scan of every ImageRepository after upgrade. On a fleet behind slow links, stagger that upgrade by ring so you do not create a registry thundering herd.
The release supports Kubernetes 1.35 to 1.37, and Flux 2.7 has reached end of life. Earlier in 2026, Flux 2.8 (February) brought Helm v4 support and CEL-based readiness checks, and Flux 2.9 (30 June) introduced the CLI plugin system that hosts Flux Mirror. The Flux project also published a post in August 2026 on selective drift correction with ignore rules, which is directly relevant to OT environments that want to tolerate certain operator-made changes; read it before designing your drift policy.
What Argo CD 3.5 changes for fleets
Argo CD 3.5 was released on 4 August 2026, and 3.3 and 3.4 were also still supported as of late October 2026 according to endoflife.date, with 3.2 having reached end of support in August. The 3.5 notes include migration from Helm 3 to Helm 4, ApplicationSet concurrency improvements for managing Applications and a Preview Apps tab, Source Hydrator enhancements (listed as promoted to beta), impersonation for server operations (listed as promoted to beta), mutual TLS for the repo server, and webhook improvements including GHCR support and jitter on webhook-triggered refreshes.
For fleets, the practical points are these. The Helm 4 migration is the first thing to test, because chart behaviour differences surface in rendering. The jitter option helps if many applications refresh on the same webhook. And impersonation matters for multi-tenant fleets, where different teams should apply to different plants with different identities. There is no explicitly labelled breaking-change section in the release notes we reviewed, so read the official upgrade guide before moving from 3.4.
Both projects follow rapid cadences: Flux has shipped minor releases roughly every few months in 2026, and Argo CD about every three months. A fleet should pin tool versions per ring and upgrade the GitOps tooling itself through the same ring process as workloads. The reconciler is a workload too.
Observability and Fleet Health
A thousand clusters produce a thousand divergent states, and the question is not “is anything wrong” but “which clusters should I look at first”. Define fleet health in terms of a few signals that both tools can export.
Reconciliation freshness. For Flux, alert when a Kustomization’s last applied revision differs from the ring pointer for longer than a threshold, or when Ready is false. For Argo CD, track sync status and last sync time per application. This is your staleness alert from the disconnected-site discussion.
Drift count. Count resources out of sync, and distinguish expected drift (autoscaler-managed replica counts, operator-owned fields) from unexpected drift. Ignore rules reduce noise: Argo CD supports ignoreDifferences on Applications, and Flux added selective drift correction with ignore rules in 2026.
Rollout success rate per ring. The most useful single metric in the whole system. If ring 1 shows rising failure rates after a revision, stop promotion automatically.
Controller health. Reconciler queue depth, error counts, restart counts and memory. Edge nodes are small, and a controller OOM-killed on a 4 GB node is a real incident.
Aggregation choices differ. With hub Argo CD or the agent, the control plane already knows application health, so a Grafana dashboard over its Prometheus metrics gives a fleet view. With per-cluster Flux, either federate Prometheus from regional collectors or use the notification-controller to emit events to a central endpoint when a Kustomization fails or recovers. In both cases, send events to a log or message system that survives the loss of the hub; an MQTT bridge to a regional broker is a natural fit in industrial settings (see MQTT store-and-forward at the edge).
Trade-offs, Gotchas, and What Goes Wrong
Every pattern above has failure modes. These are the ones that bite fleets most often.
The fight between reconcilers. Two controllers managing the same resource produce endless drift alerts and flapping rollouts. Assign every object an owner. Typical offenders are Horizontal Pod Autoscalers versus fixed replicas in manifests, and admission webhooks that mutate pods after apply.
Auto-prune is dangerous on PVCs and CRDs. Pruning a PersistentVolumeClaim or a CustomResourceDefinition deletes data. Keep prune: false for stateful platform layers, or protect resources with the kustomize.toolkit.fluxcd.io/prune: disabled annotation or Argo CD’s Prune=false sync option on specific resources.
Thundering herds on reconnect. When a regional link returns after an outage, hundreds of clusters fetch simultaneously. Use jittered intervals and registry caches at the regional tier. Argo CD’s webhook jitter and Flux’s interval settings help, but the real mitigation is capacity at the mirror.
The hub as a single point of surprise. In a hub design, upgrading Argo CD affects every site’s visibility at once. Run the hub highly available, test upgrades in a replica fleet, and understand that the argocd-agent’s principal does not yet support high availability, according to its documentation.
Secrets in Git. GitOps pressure leads teams to commit secrets. Use SOPS or sealed secrets, or external secret stores. Flux supports SOPS decryption natively and, as of 2.10, per-tenant Vault or OpenBao transit configuration; Argo CD typically uses plugins or the External Secrets Operator.
Version skew. A fleet will never be at one version. Kubernetes skew, Flux or Argo CD skew, and CRD version skew all exist simultaneously. Pin and test combinations, keep API versions current (several Flux APIs have moved to v1), and use the compatibility tables in each project’s documentation.
Stale approvals. If a change is approved on Monday and reaches ring 3 on Friday, the world may have moved. Encode expiry: promotion requires fresh checks, not just an old approval.
Over-engineering. A fleet of fifteen plants does not need an agent mesh and a custom promotion controller. Start with Flux or Argo CD plus ring pointers in Git, and add layers only when a measured problem demands them.
Practical Recommendations
Choose the topology from your connectivity profile, not from tool loyalty. If most sites have reliable, always-on links and you value a unified UI, hub-style Argo CD with ApplicationSets is the shortest path. If sites are intermittently connected, bandwidth-limited or air-gapped, choose pull: Flux in every cluster reconciling from regional OCI mirrors, or Argo CD with the agent in autonomous mode once you have validated it against your own failure scenarios.
Put rollout rings in Git, make each promotion a signed, auditable action, and let health checks and soak periods gate it. Default to prune: false and selfHeal: false for safety-critical cells, and make exceptions deliberately. Mirror everything the cluster needs, verify signatures at the cluster, and pull by digest.
A short checklist you can adopt this quarter:
- Decide topology per site class (always-connected, intermittent, air-gapped) and write it down.
- Split the repository into what-runs and where-it-runs, with one small record per cluster.
- Define four rings and encode ring membership as data, not as scripts.
- Move runtime sourcing from Git to signed OCI artifacts served from regional mirrors.
- Configure runtime registry mirrors so no cluster depends on the public internet.
- Require signature verification on artifacts and an admission policy for images.
- Alert on reconciliation staleness, not just on failures.
- Upgrade Flux or Argo CD themselves by ring, and rehearse a hub or registry outage.
- Review the Flux 2.10 and Argo CD 3.5 upgrade notes before touching production rings.
For the broader context of fleet operations, our posts on Kubernetes operators and reconciliation loops and OTA update frameworks such as SUIT, Uptane, Mender and RAUC cover the layers just below and above the GitOps control loop.
Frequently Asked Questions
Is ArgoCD or Flux better for industrial edge fleets?
Neither wins universally. Flux’s per-cluster pull model fits disconnected and bandwidth-limited sites, since clusters reconcile without a hub. Argo CD offers the richer UI and ApplicationSet templating, and with the argocd-agent it gains an inverted, agent-initiated connection suited to edge. Choose by connectivity profile and team skills, and remember that the agent project describes itself as in active development, so pilot it before committing to it for critical sites.
Can GitOps work when a factory site has no internet for days?
Yes, if the cluster never needs the internet to keep running. Reconcilers retain the last applied state and retry on return. Provide local registries for images and charts, configure runtime mirrors, and pull signed OCI artifacts from a nearby registry. For fully air-gapped plants, load offline bundles into the local registry and verify signatures on the cluster. Add staleness alerts so a long outage is visible.
How do I roll out changes plant by plant safely?
Define rings, for example lab, canary, early and broad, and make each ring track a revision pointer in Git or an OCI tag. A pipeline promotes the pointer only after health checks and a soak period pass. Argo CD offers sync windows and progressive ApplicationSet syncs; Flux uses health checks, dependencies and suspended or tag-based promotion. Check the stability level of progressive features in your version.
Should I disable auto-sync and self-heal in regulated plants?
Often, for safety-critical cells. Automated sync with selfHeal reverts operator changes, which some OT policies forbid. A common compromise is automated apply in lab and canary rings, manual or window-gated sync in production rings, and drift detection that reports without reverting. Keep prune off for stateful resources. Flux’s 2026 ignore rules and Argo CD’s ignoreDifferences reduce noise from expected drift.
What changed in Flux and Argo CD in 2026?
Argo CD 3.5 (August 2026) brought Helm 4 migration, ApplicationSet concurrency and a Source Hydrator promoted to beta per its docs. Flux 2.8 added Helm v4 and CEL readiness checks, 2.9 introduced a CLI plugin system with Flux Mirror, and 2.10 (26 October 2026) added SPIFFE mTLS, GA object identity and v1 alerting APIs. Always read each project’s upgrade notes, since Flux 2.10 has RBAC and tag-database changes.
How many clusters can one Argo CD or Flux setup manage?
We do not cite a single number because limits depend on application count, resource count, refresh intervals and sharding. Argo CD scales with controller sharding and tuned refresh settings; Flux scales naturally because each cluster reconciles itself. Load-test with a representative object count, measure memory on your actual edge hardware, and size regional mirrors for reconnect bursts rather than steady state.
Further Reading
- ArgoCD vs Flux GitOps decision record for the generic decision framework.
- K3s edge Kubernetes production guide for the cluster layer these tools run on.
- SLSA and Sigstore supply-chain architecture for artifact signing and provenance.
- WireGuard, Tailscale, NetBird and Headscale for edge fleets for fleet networking options.
- Flux 2.10 release announcement from the Flux project.
- argocd-agent documentation for the pull-style architecture and its current limitations.
- Argo CD documentation for ApplicationSets, sync windows and upgrade guides.
By Riju — about
