How to span an Istio mesh across multiple Kubernetes clusters -- and the trust federation misconfiguration that breaks cross-cluster mTLS.
Set up a basic multi-cluster mesh with east-west gateway. Know the shared root CA requirement and how to verify it. Debug cross-cluster mTLS failures.
Design multi-cluster mesh topology for multi-region HA. Own the PKI strategy across clusters. Define the upgrade procedure for multi-cluster Istio (control plane first, then data plane).
How to span an Istio mesh across multiple Kubernetes clusters -- and the trust federation misconfiguration that breaks cross-cluster mTLS.
Multi-cluster Istio configured -- primary (A) + remote (B)
A -> B calls work. B -> A calls fail with TLS verification error
CRITICALInvestigation: cluster B using different root CA than cluster A
CRITICALcacerts secret with shared root CA applied to cluster B -- B's istiod restarts
All pods restarted to get new certs signed by shared CA -- cross-cluster mTLS works
The question this raises
How does multi-cluster Istio work, what trust model does it require, and how do you diagnose cross-cluster mTLS failures?
You set up multi-cluster Istio with clusters A and B. Services in A can call services in B successfully. Services in B cannot call services in A -- TLS verification error. Both clusters have east-west gateways. What is the most likely cause?
Lesson outline
Multi-cluster Istio is powerful but the trust model is the hard part
Multi-cluster Istio allows services in different Kubernetes clusters to call each other using mTLS as if they were in the same cluster. The traffic flows via east-west gateways between clusters. The security model requires all clusters to share the same root CA -- otherwise cross-cluster mTLS certificate verification fails.
Multi-primary topology (equal clusters, own istiod):
Cluster A Cluster B
+------------------+ +------------------+
| istiod-A |<-- sync ----->| istiod-B |
| (manages A) | | (manages B) |
+------------------+ +------------------+
| East-West GW |<-- mTLS ----->| East-West GW |
| (port 15443) | | (port 15443) |
+------------------+ +------------------+
| Services A | | Services B |
+------------------+ +------------------+
Primary-remote topology (one istiod manages all):
Cluster A (primary) Cluster B (remote)
+------------------+ +------------------+
| istiod | | (no istiod) |
| (manages A+B) |<- remote secret (kubeconfig for B)
+------------------+ +------------------+
| East-West GW |<-- mTLS ----->| East-West GW |
+------------------+ +------------------+
TRUST REQUIREMENT (applies to all topologies):
Both clusters MUST share the same root CA.
Each cluster's workload SVIDs must be issued by the same root CA.
If trust roots differ: destination Envoy cannot verify source cert = mTLS FAIL.
Shared root CA setup:
1. Generate root CA (openssl or cloud KMS)
2. Create cacerts secret in BOTH clusters:
kubectl create secret generic cacerts \
-n istio-system \
--from-file=ca-cert.pem \
--from-file=ca-key.pem \
--from-file=root-cert.pem \
--from-file=cert-chain.pem
3. Install Istio AFTER cacerts exists (istiod uses it at startup)
How a service in cluster A finds and calls a service in cluster B
01
Service A in cluster A calls "service-b.namespace.svc.cluster.local"
02
Cluster A's Envoy looks up the service -- not found in cluster A's endpoint list
03
istiod in cluster A knows about cluster B services (via remote secret or mesh federation)
04
Envoy receives EDS entry for service-b in cluster B with the east-west gateway IP
05
Envoy routes to east-west gateway in cluster A (which forwards to cluster B)
06
East-west gateway in cluster A performs mTLS with east-west gateway in cluster B
07
Cluster B's east-west gateway forwards to service-b pod in cluster B
08
mTLS handshake verified using shared root CA -- SPIFFE identity validated cross-cluster
Service A in cluster A calls "service-b.namespace.svc.cluster.local"
Cluster A's Envoy looks up the service -- not found in cluster A's endpoint list
istiod in cluster A knows about cluster B services (via remote secret or mesh federation)
Envoy receives EDS entry for service-b in cluster B with the east-west gateway IP
Envoy routes to east-west gateway in cluster A (which forwards to cluster B)
East-west gateway in cluster A performs mTLS with east-west gateway in cluster B
Cluster B's east-west gateway forwards to service-b pod in cluster B
mTLS handshake verified using shared root CA -- SPIFFE identity validated cross-cluster
1# Step 1: Create shared root CA secret in BOTH clusters (before Istio install)2# (Run this against each cluster)3kubectl create secret generic cacerts -n istio-system \4--from-file=ca-cert.pem=./ca-cert.pem \5--from-file=ca-key.pem=./ca-key.pem \6--from-file=root-cert.pem=./root-cert.pem \7--from-file=cert-chain.pem=./ca-cert.pem89# Step 2: Install Istio with multi-cluster config (cluster A)10# IstioOperator with meshID and clusterName11apiVersion: install.istio.io/v1alpha112kind: IstioOperator13metadata:14name: istio15spec:16values:17global:18meshID: mesh1 # same for all clusters in mesh19clusterName: cluster-a # unique per cluster20network: network-a # network name (different if no direct pod connectivity)21components:22ingressGateways:23- name: istio-eastwestgateway24enabled: true25label:26istio: eastwestgateway27k8s:28service:29ports:30- port: 15443 # East-west traffic port31name: tls
1# Verify east-west gateway is running in both clusters2kubectl get pod -n istio-system -l istio=eastwestgateway34# Create remote secret (cluster A needs kubeconfig for cluster B)5istioctl x create-remote-secret \6--context=cluster-b \7--name=cluster-b | kubectl apply -f - --context=cluster-a89# Check that cluster A knows about cluster B services10istioctl remote-clusters --context=cluster-a11# Should show: cluster-b: SYNCED1213# Debug cross-cluster connectivity14kubectl exec -n production my-pod -c istio-proxy -- \15curl -s http://service-b.production.svc.cluster.local/healthz16# Should work if multi-cluster is configured correctly1718# Check east-west gateway for cross-cluster requests19kubectl logs -n istio-system -l istio=eastwestgateway \20-c istio-proxy | grep "cluster-b"2122# Verify shared root CA in both clusters23kubectl get secret cacerts -n istio-system --context=cluster-a \24-o jsonpath='{.data.root-cert\.pem}' | base64 -d | openssl x509 -noout -fingerprint25kubectl get secret cacerts -n istio-system --context=cluster-b \26-o jsonpath='{.data.root-cert\.pem}' | base64 -d | openssl x509 -noout -fingerprint27# Fingerprints must be identical for cross-cluster mTLS to work
Blast radius of multi-cluster misconfiguration
Installing Istio before creating the cacerts secret
# WRONG: Install Istio first, then try to add cacerts later
istioctl install --set values.global.meshID=mesh1
# Then try to add cacerts after install
kubectl create secret generic cacerts -n istio-system ...
# Problem: istiod already generated its own self-signed root CA at startup
# Restarting istiod after adding cacerts changes the CA
# All existing workload certs (signed by old self-signed CA) become invalid
# All pods must be restarted to get new certs -- service disruption# RIGHT: Create cacerts BEFORE installing Istio
# Step 1: Create the cacerts secret
kubectl create namespace istio-system --context=cluster-a
kubectl create namespace istio-system --context=cluster-b
kubectl create secret generic cacerts -n istio-system \
--context=cluster-a \
--from-file=ca-cert.pem \
--from-file=ca-key.pem \
--from-file=root-cert.pem \
--from-file=cert-chain.pem
# Same for cluster B
kubectl create secret generic cacerts -n istio-system \
--context=cluster-b \
--from-file=ca-cert.pem \
--from-file=ca-key.pem \
--from-file=root-cert.pem \
--from-file=cert-chain.pem
# Step 2: Install Istio AFTER cacerts exists
# istiod will find cacerts and use it as the CAIstio reads the cacerts secret at startup. If it is not present, istiod generates its own self-signed CA. Creating cacerts after Istio is installed requires restarting istiod AND restarting all pods to get new certs. In a multi-cluster context, this also means all cross-cluster trust is temporarily broken during the transition.
| Topology | istiod placement | Resilience | Complexity | Best for |
|---|---|---|---|---|
| Single cluster | 1 istiod in cluster | Single cluster SLA | Low | Starting point -- single region |
| Primary-remote | 1 istiod manages N clusters | Primary istiod is SPOF for remote | Medium | Dev/staging remote, tight control plane |
| Multi-primary | 1 istiod per cluster | Each cluster independently operational | High | Multi-region HA, failure isolation |
| External control plane | istiod outside all clusters | Dedicated control plane infra | Very high | Managed Istio services, large scale |
Multi-cluster trust model
📖 What the exam expects
All clusters in a multi-cluster Istio mesh must share the same root CA. Workload certificates from any cluster are signed by the same intermediate CA, allowing cross-cluster mTLS verification.
Toggle between what certifications teach and what production actually requires
Asked in senior platform and cloud architect interviews. "How would you achieve zero-downtime if one cloud region fails?" leads to multi-cluster Istio.
Common questions:
Strong answer: Mentions cacerts-before-install requirement, knows fingerprint verification step, has set up multi-cluster in practice, knows the latency overhead of east-west gateway hops.
Red flags: Does not know about the shared root CA requirement, thinks cross-cluster works automatically with just a kubeconfig, does not know about east-west gateway.
Related concepts
Explore topics that connect to this one.
Ready to see how this works in the cloud?
Switch to Career Paths for structured paths (e.g. Developer, DevOps) and provider-specific lessons.
View role-based pathsSign in to track your progress and mark lessons complete.
Questions? Discuss in the community or start a thread below.
Join DiscordSign in to start or join a thread.