How to Set Up Kubernetes Federation

How to Set Up Kubernetes Federation

Running one cluster is hard enough. Running the same application consistently across multiple clusters — different regions, different clouds, or a mix of both — introduces an entirely new category of problem: keeping configuration, policy, and placement in sync without managing each cluster by hand. Kubernetes Federation was the project’s first serious attempt at solving this, and its history matters for anyone evaluating it today.

A Necessary History Lesson: KubeFed’s Status

The original Kubernetes Federation project (v1, then v2/KubeFed) was developed under SIG Multicluster but has been effectively unmaintained for a long time — KubeFed development wound down and it never graduated to a stable, generally-recommended GA status. Anyone searching “Kubernetes Federation” today needs to know this up front, because much of what’s written about it describes a project that isn’t the active recommended path anymore. This article covers KubeFed’s concepts (since they’re genuinely useful for understanding the problem space) and then covers the tools that are actually recommended for multi-cluster management today.

The Problem Federation Was Trying to Solve

KubeFed Concepts (Historical Reference)

KubeFed introduced Federated resource types wrapping ordinary Kubernetes objects with per-cluster overrides:

apiVersion: types.kubefed.io/v1beta1
kind: FederatedDeployment
metadata:
  name: myapp
  namespace: production
spec:
  template:
    metadata:
      labels:
        app: myapp
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: myapp
      template:
        spec:
          containers:
            - name: myapp
              image: registry.example.com/myapp:1.0.0
  placement:
    clusters:
      - name: cluster-us-east
      - name: cluster-eu-west
  overrides:
    - clusterName: cluster-eu-west
      clusterOverrides:
        - path: "/spec/replicas"
          value: 5

This is worth understanding conceptually even though KubeFed itself isn’t the recommended production path anymore — the “template + placement + per-cluster overrides” model reappears in the tools that replaced it.

What’s Actually Recommended Today: Argo CD ApplicationSets

For GitOps-style multi-cluster deployment, Argo CD’s ApplicationSet controller is the modern, actively maintained equivalent, using generators to fan a single template out across a cluster list:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapp
  namespace: argocd
spec:
  generators:
    - clusters: {}
  template:
    metadata:
      name: '{{name}}-myapp'
    spec:
      project: default
      source:
        repoURL: https://github.com/example/manifests.git
        targetRevision: main
        path: production
      destination:
        server: '{{server}}'
        namespace: production
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
kubectl apply -f myapp-applicationset.yaml -n argocd
kubectl -n argocd get applications
NAME                  SYNC STATUS   HEALTH STATUS
cluster-us-myapp      Synced        Healthy
cluster-eu-myapp      Synced        Healthy

Registering additional clusters with Argo CD:

argocd cluster add cluster-eu-west-context --name cluster-eu-west

Cluster Registration and Access

Argo CD (like KubeFed before it) needs credentials to reach each member cluster’s API server. This is managed via kubeconfig contexts and Argo CD Secrets:

apiVersion: v1
kind: Secret
metadata:
  name: cluster-eu-west
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
  name: cluster-eu-west
  server: https://eu-west-cluster-api.example.com
  config: |
    {
      "bearerToken": "...",
      "tlsClientConfig": {
        "insecure": false,
        "caData": "..."
      }
    }

Service Mesh Alternative: Multi-Cluster Networking

A related but distinct problem is networking across clusters (as opposed to deploying across clusters) — service meshes like Istio and Cilium’s ClusterMesh address this by letting Services in one cluster discover and call Services in another directly:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: multicluster
spec:
  values:
    global:
      meshID: mesh1
      multiCluster:
        clusterName: cluster-us-east
      network: network1

This solves a genuinely different problem than ApplicationSets/KubeFed — cross-cluster service discovery and traffic routing, rather than keeping deployed resources in sync — and the two are often used together in serious multi-cluster architectures.

RBAC Across Clusters

Multi-cluster tooling needs to be granted access per member cluster, scoped as tightly as single-cluster RBAC would be:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: argocd-manager
rules:
  - apiGroups: ["*"]
    resources: ["*"]
    verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: argocd-manager-binding
subjects:
  - kind: ServiceAccount
    name: argocd-manager
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: argocd-manager
  apiGroup: rbac.authorization.k8s.io

In practice, scope this down per-organization rather than granting blanket wildcard access — the example above mirrors Argo CD’s own default bootstrap role but should be tightened for anything beyond initial evaluation.

Placement Strategies

Real multi-cluster placement decisions typically factor in:

ApplicationSet generators support list-based, cluster-label-based, and Git-directory-based placement, letting these strategies be expressed declaratively rather than hardcoded per deployment.

Monitoring a Multi-Cluster Fleet

Federating observability itself is its own challenge — Thanos or Grafana Mirror/Cortex are the common patterns for aggregating Prometheus metrics across clusters into a single queryable view:

apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: main
  namespace: monitoring
spec:
  thanos:
    objectStorageConfig:
      key: thanos.yaml
      name: thanos-objstore-config
kubectl -n argocd get applicationsets
kubectl -n argocd get applications -l app.kubernetes.io/instance=myapp

Why Teams End Up Needing Multi-Cluster At All

It’s worth being explicit about the actual drivers, since “just use one big cluster” is often the right answer and multi-cluster complexity shouldn’t be adopted casually:

Multi-cluster tooling is the answer to a real problem, but it also multiplies operational surface area — every cluster needs its own upgrade cadence, its own monitoring, its own on-call familiarity — so it’s worth confirming the driver above is a genuine requirement before adopting it purely because it’s available.

Disaster Recovery as a Placement Strategy

Beyond routine multi-region deployment, a common and often underappreciated use of multi-cluster placement is disaster recovery itself — keeping a warm or cold standby cluster ready to receive traffic if the primary region becomes unavailable:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapp-dr
  namespace: argocd
spec:
  generators:
    - list:
        elements:
          - cluster: cluster-primary
            replicas: "5"
          - cluster: cluster-dr-standby
            replicas: "1"
  template:
    metadata:
      name: '{{cluster}}-myapp'
    spec:
      source:
        repoURL: https://github.com/example/manifests.git
        targetRevision: main
        path: production
        helm:
          parameters:
            - name: replicaCount
              value: '{{replicas}}'
      destination:
        server: '{{cluster}}'
        namespace: production

The standby cluster runs at reduced capacity (replicas: 1) continuously, staying warm and ready, and a failover event (DNS cutover, load balancer reweighting) simply redirects traffic and scales the standby cluster up — a meaningfully faster recovery path than provisioning a cluster from scratch after an incident has already begun.

Alternative: Config Sync for Policy-Heavy Multi-Cluster Fleets

Argo CD’s ApplicationSets are the most common choice for application deployment across a fleet, but for organizations whose primary multi-cluster need is enforcing consistent policy and configuration — RBAC baselines, NetworkPolicies, resource quotas — rather than application rollout specifically, Google’s Config Sync (part of Anthos Config Management, also usable independently of GKE) takes a slightly different angle, treating an entire Git repository as the source of truth for cluster configuration and continuously reconciling every registered cluster against it:

apiVersion: configsync.gke.io/v1beta1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-management-system
spec:
  sourceFormat: unstructured
  git:
    repo: https://github.com/example/cluster-config.git
    branch: main
    dir: "clusters/production"
    auth: none

The conceptual overlap with Argo CD ApplicationSets is real — both are pull-based reconciliation against Git — but Config Sync leans more heavily toward policy and baseline configuration as its primary use case, while Argo CD’s ecosystem (Applications, ApplicationSets, Rollouts) is more oriented around application deployment workflows specifically. Some organizations run both side by side: Config Sync for cluster-wide policy baselines every cluster must satisfy, and Argo CD for the actual application rollouts layered on top of that baseline.

Evaluating Whether a Team Is Actually Ready for Multi-Cluster

Before adopting any of the tooling covered in this article, it’s worth an honest gut-check: does the team already have solid single-cluster operational practices — monitoring, RBAC discipline, tested backup/restore, a working CI/CD pipeline — genuinely in place? Multi-cluster tooling multiplies whatever operational maturity already exists; it doesn’t substitute for it. A team that hasn’t yet nailed reliable single-cluster operations will generally find that adopting multi-cluster federation on top of that gap multiplies the underlying problems across every cluster in the fleet, rather than solving them. The tooling in this article is genuinely valuable once the actual driver (data residency, blast-radius isolation, disaster recovery, geographic latency) is real and well understood — it’s considerably less valuable when adopted speculatively, ahead of any concrete requirement, purely because it’s available.

Common Mistakes

Summary

Kubernetes Federation, as originally conceived (KubeFed), isn’t the recommended path for multi-cluster management today — the concepts it introduced (templates, placement, per-cluster overrides) live on more successfully in tools like Argo CD’s ApplicationSets, with service meshes handling the separate problem of cross-cluster networking. For anyone starting multi-cluster work now, ApplicationSets plus a service mesh (if cross-cluster service calls are actually needed) is the more supportable, actively maintained combination.

References

Exit mobile version