Shared control plane (single and multiple networks)
Follow this guide to set up a multicluster Istio service mesh across multiple clusters with a shared control plane.
In this configuration, multiple Kubernetes remote clusters connect to a shared Istio
control plane running in a primary cluster. Remote clusters can be in the same network as the primary cluster or in different networks. After one or more remote clusters are connected, the control plane of the primary cluster will manage the service mesh across all service endpoints.Prerequisites
Two or more clusters running a supported Kubernetes version (1.16, 1.17, 1.18).
All Kubernetes control plane API servers must be routable to each other.
Clusters on the same network must be an RFC1918 network, VPN, or an alternative more advanced network technique meeting the following requirements:
- Individual cluster Pod CIDR ranges and service CIDR ranges must be unique across the network and may not overlap.
- All pod CIDRs in the same network must be routable to each other.
Clusters on different networks must have
istio-ingressgateway
services which are accessible from every other cluster, ideally using L4 network load balancers (NLB). Not all cloud providers support NLBs and some require special annotations to use them, so please consult your cloud provider’s documentation for enabling NLBs for service object type load balancers. When deploying on platforms without NLB support, it may be necessary to modify the health checks for the load balancer to register the ingress gateway.
Preparation
Certificate Authority
Generate intermediate CA certificates for each cluster’s CA from your organization’s root CA. The shared root CA enables mutual TLS communication across different clusters. For illustration purposes, the following instructions use the certificates from the Istio samples directory for both clusters.
Run the following commands on each cluster in the mesh to install the certificates. See Certificate Authority (CA) certificates2 for more details on configuring an external CA.
Cross-cluster control plane access
Decide how to expose the primary cluster’s Istiod discovery service to the remote clusters. Pick one of the two options:
Option (1) - Use the
istio-ingressgateway
gateway shared with data traffic.Option (2) - Use a cloud provider’s internal load balancer on the Istiod service. For additional requirements and restrictions that may apply when using an internal load balancer between clusters, see Kubernetes internal load balancer documentation and your cloud provider’s documentation.
Cluster and network naming
Determine the name of the clusters and networks in the mesh. These names will be used
in the mesh network configuration and when configuring the mesh’s service registries.
Assign a unique name to each cluster. The name must be a
DNS label name.
In the example below the primary cluster is called main0
and the remote cluster is remote0
.
If the clusters are on different networks, assign a unique network name for each network.
If clusters are on the same network, the same network name is used for those clusters.
Deployment
Primary cluster
Create the primary cluster’s configuration. Pick one of the two options for cross-cluster control plane access.
Apply the primary cluster’s configuration.
Wait for the control plane to be ready before proceeding.
Set the ISTIOD_REMOTE_EP
environment variable based on which remote control
plane configuration option was selected earlier.
Remote cluster
Create the remote cluster’s configuration.
Apply the remote cluster configuration.
Wait for the remote cluster to be ready.
Cross-cluster load balancing
Configure ingress gateways
Cross-network traffic is securely routed through each destination cluster’s ingress gateway. When clusters in a mesh are on different networks you need to configure port 443 on the ingress gateway to pass incoming traffic through to the target service specified in a request’s SNI header, for SNI values of the local top-level domain (i.e., the Kubernetes DNS domain7). Mutual TLS connections will be used all the way from the source to the destination sidecar.
Apply the following configuration to each cluster.
Configure cross-cluster service registries
To enable cross-cluster load balancing, the Istio control plane requires
access to all clusters in the mesh to discover services, endpoints, and
pod attributes. To configure access, create a secret for each remote
cluster with credentials to access the remote cluster’s kube-apiserver
and
install it in the primary cluster. This secret uses the credentials of the
istio-reader-service-account
in the remote cluster. --name
specifies the
remote cluster’s name. It must match the cluster name in primary cluster’s IstioOperator
configuration.
Deploy an example service
Deploy two instances of the helloworld
service, one in each cluster. The difference
between the two instances is the version of their helloworld
image.
Deploy helloworld v2 in the remote cluster
Create a
sample
namespace with a sidecar auto-injection label:Deploy
helloworld v2
:Confirm
helloworld v2
is running:
Deploy helloworld v1 in the primary cluster
Create a
sample
namespace with a sidecar auto-injection label:Deploy
helloworld v1
:Confirm
helloworld v1
is running:
Cross-cluster routing in action
To demonstrate how traffic to the helloworld
service is distributed across the two clusters,
call the helloworld
service from another in-mesh sleep
service.
Deploy the
sleep
service in both clusters:Wait for the
sleep
service to start in each cluster:Call the
helloworld.sample
service several times from the primary cluster:Call the
helloworld.sample
service several times from the remote cluster:
If set up correctly, the traffic to the helloworld.sample
service will be distributed between instances
on the main and remote clusters resulting in responses with either v1
or v2
in the body:
You can also verify the IP addresses used to access the endpoints with istioctl proxy-config
.
In the primary cluster, the endpoints are the gateway IP of the remote cluster (192.23.120.32:443
) and
the helloworld pod IP in the primary cluster (10.10.0.90:5000
).
In the remote cluster, the endpoints are the gateway IP of the primary cluster (192.168.1.246:443
) and
the pod IP in the remote cluster (10.32.0.9:5000
).
Congratulations!
You have configured a multi-cluster Istio mesh, installed samples and verified cross cluster traffic routing.
Additional considerations
Automatic injection
The Istiod service in each cluster provides automatic sidecar injection for proxies in its own cluster. Namespaces must be labeled in each cluster following the automatic sidecar injection guide
Access services from different clusters
Kubernetes resolves DNS on a cluster basis. Because the DNS resolution is tied
to the cluster, you must define the service object in every cluster where a
client runs, regardless of the location of the service’s endpoints. To ensure
this is the case, duplicate the service object to every cluster using
kubectl
. Duplication ensures Kubernetes can resolve the service name in any
cluster. Since the service objects are defined in a namespace, you must define
the namespace if it doesn’t exist, and include it in the service definitions in
all clusters.
Security
The Istiod service in each cluster provides CA functionality to proxies in its own cluster. The CA setup earlier ensures proxies across clusters in the mesh have the same root of trust.
Uninstalling the remote cluster
To uninstall the remote cluster, run the following command:
To uninstall the primary cluster, run the following command: