Multi-Cluster Basics
This section covers the hands-on mechanics of working across more than one Kubernetes cluster: managing contexts, drawing region and environment boundaries, and delivering the same workload to several clusters safely.
Search across all documentation pages
This section covers the hands-on mechanics of working across more than one Kubernetes cluster: managing contexts, drawing region and environment boundaries, and delivering the same workload to several clusters safely.
kubectl matching within one minor.~/.kube/config.# Merge several kubeconfigs into one and confirm the contexts
export KUBECONFIG=~/.kube/prod-us:~/.kube/prod-eu:~/.kube/staging
kubectl config view --flatten > ~/.kube/config
kubectl config get-contextsEach cluster is a context in your kubeconfig; switching contexts is how you point kubectl at a different cluster.
kubectl config get-contexts
kubectl config use-context prod-eu
kubectl get nodesuse-context sets the default target for every later command.kubectl config current-context before applying to production.Use --context for a one-off so you never accidentally leave kubectl pointed at the wrong cluster.
kubectl --context prod-us get deploy -n web
kubectl --context prod-eu get deploy -n web--context overrides the current context for a single command.use-context.-n <namespace> to be fully explicit about target and scope.Consistent naming is the cheapest fleet tool you have.
# context name pattern: <env>-<region>
prod-us-east
prod-eu-west
staging-us-eastkubectl config get-contexts groups them naturally.Standard topology labels let the scheduler and your tooling reason about location.
kubectl get nodes -L topology.kubernetes.io/region,topology.kubernetes.io/zonetopology.kubernetes.io/region and .../zone are well-known labels set by cloud providers.topologySpreadConstraints and zonal spreading.Use a cluster boundary for upgrade risk, and namespaces for team isolation inside it.
apiVersion: v1
kind: Namespace
metadata:
name: team-payments
labels:
pod-security.kubernetes.io/enforce: restrictedrestricted Pod Security Standard is the safe default for workload namespaces.Quotas stop one team from starving a shared cluster.
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-payments-quota
namespace: team-payments
spec:
hard:
requests.cpu: "20"
requests.memory: 40Gi
limits.cpu: "40"
limits.memory: 80Girequests reserve capacity; limits cap burst.LimitRange to supply defaults so pods without requests still schedule.Helm plus a per-cluster values file is the simplest multi-cluster delivery.
helm upgrade --install web ./charts/web \
--kube-context prod-us --values values/prod-us.yaml
helm upgrade --install web ./charts/web \
--kube-context prod-eu --values values/prod-eu.yaml--kube-context targets the release without changing your current context.Topology spread keeps a workload available when one zone fails.
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: webmaxSkew: 1 keeps replica counts nearly even across zones.DoNotSchedule refuses to place a pod that would violate the spread.ScheduleAnyway if availability matters more than perfect balance.Keep base config shared and let each cluster override only what differs.
apiVersion: v1
kind: ConfigMap
metadata:
name: web-config
namespace: web
data:
REGION: "eu-west"
DB_HOST: "db.eu-west.internal"Never assume a multi-cluster apply succeeded everywhere.
for ctx in prod-us prod-eu; do
echo "== $ctx =="
kubectl --context "$ctx" rollout status deploy/web -n web --timeout=120s
donerollout status blocks until the deployment is healthy or times out.Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).
Reviewed by Chris St. John·Last updated Jul 16, 2026