Cluster two - secondary
This process will add a second cluster to the mesh - note that the second cluster maintains its own Kubernetes context and independent control plane so that it is only the service mesh that spans clusters.
Begin by configuring the namespace, similar to cluster1 above:
$ kubectl --context="${CTX_CLUSTER2}" create namespace istio-system
$ kubectl --context="${CTX_CLUSTER2}" annotate namespace istio-system topology.istio.io/controlPlaneClusters=cluster1
As before, create a secret using the pre-shared SSL certificate:
$ pushd certs
$ kubectl --context="${CTX_CLUSTER2}" create secret generic cacerts -n istio-system \
--from-file=cluster2/ca-cert.pem \
--from-file=cluster2/ca-key.pem \
--from-file=cluster2/root-cert.pem \
--from-file=cluster2/cert-chain.pem
$ popd
Create a configuration file for the IstioOperator custom resource similar to cluster1 but referencing the gateway created above:
$ export DISCOVERY_ADDRESS=$(kubectl \
--context="${CTX_CLUSTER1}" \
-n istio-system get svc istio-eastwestgateway \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ cat <<EOF > cluster2.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
profile: remote
values:
istiodRemote:
injectionPath: /inject/cluster/cluster2/net/network1
global:
remotePilotAddress: ${DISCOVERY_ADDRESS}
EOF
Use the configuration file to install Istio service mesh:
$ istioctl install --context="${CTX_CLUSTER2}" -f cluster2.yaml
This will install the Istio 1.16.0 remote profile with ["Istiod remote"] components into the cluster. Proceed? (y/N) y
✔ Istiod remote installed
✔ Installation complete Making this installation the default for injection and validation.
Thank you for installing Istio 1.16. Please take a few minutes to tell us about your install/upgrade experience!
To complete the cross-cluster attachment, create a secret on cluster1 that contains the cluster configuration for cluster2:
$ istioctl x create-remote-secret \
--context="${CTX_CLUSTER2}" \
--name=cluster2 | \
kubectl apply -f - --context="${CTX_CLUSTER1}"
secret/istio-remote-secret-cluster2 created
Verify the multi-cluster mesh
To verify that routing is working correctly between clusters, establish a service on each cluster that publicizes its respective location, in this case using a version string. Fortunately, the Istio project conveniently makes such a service available.
On each cluster, create a Namespace for testing and ensure that the Namespace if configured for injecting the Istio sidecar:
$ kubectl create --context="${CTX_CLUSTER1}" namespace sample && \
kubectl label --context="${CTX_CLUSTER1}" namespace sample \
istio-injection=enabled
namespace/sample created
namespace/sample labeled
$ kubectl create --context="${CTX_CLUSTER2}" namespace sample && \
kubectl label --context="${CTX_CLUSTER2}" namespace sample \
istio-injection=enabled
namespace/sample created
namespace/sample labeled
On each cluster deploy the helloworld service from the Istio repository:
$ kubectl apply --context="${CTX_CLUSTER1}" \
-f samples/helloworld/helloworld.yaml \
-l service=helloworld -n sample
service/helloworld created
$ kubectl apply --context="${CTX_CLUSTER2}" \
-f samples/helloworld/helloworld.yaml \
-l service=helloworld -n sample
service/helloworld created
On each cluster, deploy a version of the helloworld deployment:
$ kubectl apply --context="${CTX_CLUSTER1}" \
-f samples/helloworld/helloworld.yaml \
-l version=v1 -n sample
deployment.apps/helloworld-v1 created
$ kubectl apply --context="${CTX_CLUSTER2}" \
-f samples/helloworld/helloworld.yaml \
-l version=v2 -n sample
deployment.apps/helloworld-v2 created
On each cluster, deploy the sleep deployment, service, and service account. Sleep provides a convenient curl environment:
$ kubectl apply --context="${CTX_CLUSTER1}" \
-f samples/sleep/sleep.yaml -n sample
serviceaccount/sleep created
service/sleep created
deployment.apps/sleep created
$ kubectl apply --context="${CTX_CLUSTER2}" \
-f samples/sleep/sleep.yaml -n sample
serviceaccount/sleep created
service/sleep created
deployment.apps/sleep created