Learning GitOps - FluxCD - Multi-Cluster Management
Episode 23 of 36

Learning GitOps - FluxCD - Multi-Cluster Management

Managing many Kubernetes clusters with FluxCD: cluster strategies per environment, geography, tenant, and hub-and-spoke, multi-cluster bootstrap, cross-cluster dependencies for service discovery and secret sharing, and Cluster API and vcluster integration.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 22 you secured secrets with Sealed Secrets — Git can now be a safe home for secret configuration. But there's a scale we haven't touched: real organizations don't run on a single cluster. There's staging, production, maybe one cluster per region or per team. Each cluster means an environment, configuration, and workflow that must be managed.

This episode covers multi-cluster management with FluxCD: strategies for choosing a cluster topology, bootstrapping many clusters from Git, cross-cluster dependencies such as service discovery and secret sharing, and integration with Cluster API, vcluster, and multi-cluster service meshes.

Multi-Cluster Strategies

There's no single right model — the choice depends on isolation, latency, and cost. Four common patterns:

StrategyWhen to useAdvantage
Cluster per environmentSeparating prod vs stagingSmall blast radius, independent environments
Geographic distributionUsers spread across regionsLow latency, regional HA
Tenant per clusterMulti-tenant SaaSStrict tenant isolation
Hub-and-spokeMany workloads, centralized controlCentralized configuration, independent spokes

The hub-and-spoke pattern is the most popular for GitOps at scale: a hub (or central repository) becomes the source of truth, while each spoke cluster pulls the relevant configuration. Git acts as the communication bus between clusters.

Multi-Cluster Bootstrap

Bootstrapping Each Cluster

Flux is bootstrapped per cluster, each pointing to a different path in the same repository:

Bootstrap two clusters
flux bootstrap github \
  --owner=devvnull --repository=gitops-production \
  --branch=main --path=clusters/production --personal
 
flux bootstrap github \
  --owner=devvnull --repository=gitops-production \
  --branch=main --path=clusters/staging --personal

Each bootstrap creates its own Git connection, its own credentials, and its own flux-system namespace. The directory structure becomes the main organizational pattern:

Multi-cluster repo structure
clusters/
├── production/
   ├── flux-system/
   └── apps/
├── staging/
   ├── flux-system/
   └── apps/
└── shared/
    ├── base/
    └── kustomization.yaml

Shared vs Cluster-Specific Manifests

Manifests that are identical in all clusters (e.g. monitoring, logging, policy) only need to be written once in shared/base and used together. Manifests that differ per cluster (e.g. resource sizes, replica counts, endpoints) are written in each cluster's own path.

Flux connects the two through an additional Kustomization pointing at the shared repository, or through a kustomize overlay that references the same base:

clusters/production/shared-kustomization.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: shared
  namespace: flux-system
spec:
  interval: 5m
  sourceRef:
    kind: GitRepository
    name: shared
  path: ./shared/base
  prune: true

Cross-Cluster Dependencies

Clusters rarely stand alone. The three most common dependencies:

Service Discovery

An application in cluster A calls a service in cluster B. A multi-cluster service mesh solves this transparently: Istio multi-primary lets a VirtualService reference a service in another cluster, while Linkerd multicluster "mirroring" copies Services from a remote cluster to the local cluster:

Linkerd service mirroring
linkerd multicluster link --cluster-name production | kubectl apply -f -
linkerd multicluster check

Sharing Secrets

Secrets can be shared between clusters in several ways: Sealed Secrets with the same key restored to each cluster (episode 22), or ESO with one central backend accessed by all clusters (episode 21). The choice between Git-ciphertext and an external backend applies the same way at the multi-cluster level.

Configuration Propagation

Configuration changes are spread through Git: push to the repository, and each cluster pulls the changes on its own interval. Because each cluster has its own Kustomization, the rollout can be managed — for example staging follows automatically, while production waits for approval via a change in a path protected by branch protection.

Tip

Staged propagation uses the promotion pattern: configuration is tested in the clusters/staging path first, then copied to clusters/production through a pull request. Git provides a complete audit trail for every change between environments.

Tools Integration

Cluster API

Cluster API (CAPI) makes the cluster itself a declaratively managed resource — and because CAPI is a Kubernetes application, it can also run through Flux on a management cluster:

clusters/mgmt/cluster.yaml
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: workload-production
  namespace: clusters
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
        - 10.244.0.0/16
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: AWSCluster
    name: workload-production

vcluster

vcluster creates virtual clusters inside a physical cluster — each vcluster is an isolated namespace with its own API server. This is cheap for many tenants and pairs very well with Flux: each vcluster is bootstrapped as a separate cluster with its own Flux credentials, without adding hardware.

Multi-Cluster Service Mesh

A multi-cluster service mesh unifies identity and security policy across clusters: Istio multi-primary for failover and cross-cluster traffic split, Linkerd multicluster for simple service mirroring, or AWS App Mesh for a regional mesh. mTLS and access policies become consistent across all clusters. Verify inter-cluster connectivity with linkerd multicluster check.

Closing

This episode closes the multi-cluster phase: FluxCD doesn't just sync a single cluster, it becomes the foundation for managing dozens of clusters from one or several repositories. The strategy is chosen based on isolation and latency needs, bootstrap runs per cluster with a separate path, cross-cluster dependencies are handled through service meshes, secret sharing, and Git as the propagation medium.

The key takeaways:

  • The strategy determines the architecture: cluster per environment, geographic, tenant, or hub-and-spoke according to need.
  • Repeated bootstrap per cluster: each cluster has its own path, credentials, and flux-system.
  • Separate shared and specific: shared manifests in base, environment differences in each overlay.
  • Git is the bus between clusters: configuration is propagated and promoted through pull requests.
  • Tools extend the reach: Cluster API manages cluster lifecycle, vcluster isolates tenants, service meshes unify network policy.

With many clusters, new challenges appear: the same configuration is spread out and must stay consistent, and each cluster's resources must be watched. In the next episode, episode 24, we'll discuss Sharding and Performance: horizontal and vertical Flux sharding, reconciliation tuning, and large-scale repository patterns. See you in episode 24!

Learning GitOps - FluxCD - Multi-Cluster Management | Learn FluxCD & GitOps