@@ -490,54 +490,117 @@ You can use the Sail Operator and the Sail CRDs to manage a multi-cluster Istio
490490
491491These steps are common to every multi-cluster deployment and should be completed *after* meeting the prerequisites but *before* starting on a specific deployment model.
492492
493- 1. Setup env vars .
493+ 1. Setup environment variables .
494494
495495 ` ` ` sh
496496 export CTX_CLUSTER1=<cluster1-ctx>
497497 export CTX_CLUSTER2=<cluster2-ctx>
498- export ISTIO_VERSION=1.23.0
498+ export ISTIO_VERSION=1.23.2
499499 ` ` `
500500
5015012. Create `istio-system` namespace on each cluster.
502502
503503 ` ` ` sh
504504 kubectl get ns istio-system --context "${CTX_CLUSTER1}" || kubectl create namespace istio-system --context "${CTX_CLUSTER1}"
505+ kubectl get ns istio-system --context "${CTX_CLUSTER2}" || kubectl create namespace istio-system --context "${CTX_CLUSTER2}"
505506 ` ` `
506507
508+ 4. Create a shared root certificate.
509+
510+ If you have [established trust](https://istio.io/latest/docs/setup/install/multicluster/before-you-begin/#configure-trust) between your clusters already you can skip this and the following steps.
511+
507512 ` ` ` sh
508- kubectl get ns istio-system --context "${CTX_CLUSTER2}" || kubectl create namespace istio-system --context "${CTX_CLUSTER2}"
509- ` ` `
513+ openssl genrsa -out root-key.pem 4096
514+ cat <<EOF > root-ca.conf
515+ [ req ]
516+ encrypt_key = no
517+ prompt = no
518+ utf8 = yes
519+ default_md = sha256
520+ default_bits = 4096
521+ req_extensions = req_ext
522+ x509_extensions = req_ext
523+ distinguished_name = req_dn
524+ [ req_ext ]
525+ subjectKeyIdentifier = hash
526+ basicConstraints = critical, CA:true
527+ keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, keyCertSign
528+ [ req_dn ]
529+ O = Istio
530+ CN = Root CA
531+ EOF
510532
511- 3. Create shared trust and add intermediate CAs to each cluster.
533+ openssl req -sha256 -new -key root-key.pem \
534+ -config root-ca.conf \
535+ -out root-cert.csr
512536
513- If you already have a [shared trust](https://istio.io/latest/docs/setup/install/multicluster/before-you-begin/#configure-trust) for each cluster you can skip this. Otherwise, you can use the instructions below to create a shared trust and push the intermediate CAs into your clusters.
537+ openssl x509 -req -sha256 -days 3650 \
538+ -signkey root-key.pem \
539+ -extensions req_ext -extfile root-ca.conf \
540+ -in root-cert.csr \
541+ -out root-cert.pem
542+ ` ` `
543+ 5. Create intermediate certiciates.
514544
515- Create a self signed root CA and intermediate CAs.
516545 ` ` ` sh
517- mkdir -p certs
518- pushd certs
519- curl -fsL -o common.mk "https://raw.githubusercontent.com/istio/istio/${ISTIO_VERSION}/tools/certs/common.mk"
520- curl -fsL -o Makefile.selfsigned.mk "https://raw.githubusercontent.com/istio/istio/${ISTIO_VERSION}/tools/certs/Makefile.selfsigned.mk"
521- make -f Makefile.selfsigned.mk root-ca
522- make -f Makefile.selfsigned.mk east-cacerts
523- make -f Makefile.selfsigned.mk west-cacerts
524- popd
546+ for cluster in west east; do
547+ mkdir $cluster
548+
549+ openssl genrsa -out ${cluster}/ca-key.pem 4096
550+ cat <<EOF > ${cluster}/intermediate.conf
551+ [ req ]
552+ encrypt_key = no
553+ prompt = no
554+ utf8 = yes
555+ default_md = sha256
556+ default_bits = 4096
557+ req_extensions = req_ext
558+ x509_extensions = req_ext
559+ distinguished_name = req_dn
560+ [ req_ext ]
561+ subjectKeyIdentifier = hash
562+ basicConstraints = critical, CA:true, pathlen:0
563+ keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, keyCertSign
564+ subjectAltName=@san
565+ [ san ]
566+ DNS.1 = istiod.istio-system.svc
567+ [ req_dn ]
568+ O = Istio
569+ CN = Intermediate CA
570+ L = $cluster
571+ EOF
572+
573+ openssl req -new -config ${cluster}/intermediate.conf \
574+ -key ${cluster}/ca-key.pem \
575+ -out ${cluster}/cluster-ca.csr
576+
577+ openssl x509 -req -sha256 -days 3650 \
578+ -CA root-cert.pem \
579+ -CAkey root-key.pem -CAcreateserial \
580+ -extensions req_ext -extfile ${cluster}/intermediate.conf \
581+ -in ${cluster}/cluster-ca.csr \
582+ -out ${cluster}/ca-cert.pem
583+
584+ cat ${cluster}/ca-cert.pem root-cert.pem \
585+ > ${cluster}/cert-chain.pem
586+ cp root-cert.pem ${cluster}
587+ done
525588 ` ` `
526589
527- Push the intermediate CAs to each cluster.
590+ 6. Push the intermediate CAs to each cluster.
528591 ` ` ` sh
529592 kubectl --context "${CTX_CLUSTER1}" label namespace istio-system topology.istio.io/network=network1
530593 kubectl get secret -n istio-system --context "${CTX_CLUSTER1}" cacerts || kubectl create secret generic cacerts -n istio-system --context "${CTX_CLUSTER1}" \
531- --from-file=certs/ east/ca-cert.pem \
532- --from-file=certs/ east/ca-key.pem \
533- --from-file=certs/ east/root-cert.pem \
534- --from-file=certs/ east/cert-chain.pem
594+ --from-file=east/ca-cert.pem \
595+ --from-file=east/ca-key.pem \
596+ --from-file=east/root-cert.pem \
597+ --from-file=east/cert-chain.pem
535598 kubectl --context "${CTX_CLUSTER2}" label namespace istio-system topology.istio.io/network=network2
536599 kubectl get secret -n istio-system --context "${CTX_CLUSTER2}" cacerts || kubectl create secret generic cacerts -n istio-system --context "${CTX_CLUSTER2}" \
537- --from-file=certs/ west/ca-cert.pem \
538- --from-file=certs/ west/ca-key.pem \
539- --from-file=certs/ west/root-cert.pem \
540- --from-file=certs/ west/cert-chain.pem
600+ --from-file=west/ca-cert.pem \
601+ --from-file=west/ca-key.pem \
602+ --from-file=west/root-cert.pem \
603+ --from-file=west/cert-chain.pem
541604 ` ` `
542605
543606# ## Multi-Primary - Multi-Network
@@ -566,22 +629,27 @@ These installation instructions are adapted from: https://istio.io/latest/docs/s
566629 clusterName: cluster1
567630 network: network1
568631 EOF
632+ ` ` `
633+
634+ 2. Wait for the control plane to become ready.
635+
636+ ` ` ` sh
569637 kubectl wait --context "${CTX_CLUSTER1}" --for=condition=Ready istios/default --timeout=3m
570638 ` ` `
571639
572- 2 . Create east-west gateway on `cluster1`.
640+ 3 . Create east-west gateway on `cluster1`.
573641
574642 ` ` ` sh
575643 kubectl apply --context "${CTX_CLUSTER1}" -f https://raw.githubusercontent.com/istio-ecosystem/sail-operator/main/docs/multicluster/east-west-gateway-net1.yaml
576644 ` ` `
577645
578- 3 . Expose services on `cluster1`.
646+ 4 . Expose services on `cluster1`.
579647
580648 ` ` ` sh
581649 kubectl --context "${CTX_CLUSTER1}" apply -n istio-system -f https://raw.githubusercontent.com/istio-ecosystem/sail-operator/main/docs/multicluster/expose-services.yaml
582650 ` ` `
583651
584- 4 . Create `Istio` resource on `cluster2`.
652+ 5 . Create `Istio` resource on `cluster2`.
585653
586654 ` ` ` sh
587655 kubectl apply --context "${CTX_CLUSTER2}" -f - <<EOF
@@ -599,22 +667,27 @@ These installation instructions are adapted from: https://istio.io/latest/docs/s
599667 clusterName: cluster2
600668 network: network2
601669 EOF
670+ ` ` `
671+
672+ 6. Wait for the control plane to become ready.
673+
674+ ` ` ` sh
602675 kubectl wait --context "${CTX_CLUSTER2}" --for=jsonpath='{.status.revisions.ready}'=1 istios/default --timeout=3m
603676 ` ` `
604677
605- 5 . Create east-west gateway on `cluster2`.
678+ 7 . Create east-west gateway on `cluster2`.
606679
607680 ` ` ` sh
608681 kubectl apply --context "${CTX_CLUSTER2}" -f https://raw.githubusercontent.com/istio-ecosystem/sail-operator/main/docs/multicluster/east-west-gateway-net2.yaml
609682 ` ` `
610683
611- 6 . Expose services on `cluster2`.
684+ 8 . Expose services on `cluster2`.
612685
613686 ` ` ` sh
614687 kubectl --context "${CTX_CLUSTER2}" apply -n istio-system -f https://raw.githubusercontent.com/istio-ecosystem/sail-operator/main/docs/multicluster/expose-services.yaml
615688 ` ` `
616689
617- 7 . Install a remote secret in `cluster2` that provides access to the `cluster1` API server.
690+ 9 . Install a remote secret in `cluster2` that provides access to the `cluster1` API server.
618691
619692 ` ` ` sh
620693 istioctl create-remote-secret \
@@ -634,7 +707,7 @@ These installation instructions are adapted from: https://istio.io/latest/docs/s
634707 kubectl apply -f - --context "${CTX_CLUSTER2}"
635708 ` ` `
636709
637- 8 . Install a remote secret in `cluster1` that provides access to the `cluster2` API server.
710+ 10 . Install a remote secret in `cluster1` that provides access to the `cluster2` API server.
638711
639712 ` ` ` sh
640713 istioctl create-remote-secret \
@@ -643,7 +716,7 @@ These installation instructions are adapted from: https://istio.io/latest/docs/s
643716 kubectl apply -f - --context="${CTX_CLUSTER1}"
644717 ` ` `
645718
646- If using kind, first get the `cluster1` controlplane IP and pass the `--server` option to `istioctl create-remote-secret`
719+ ** If using kind** , first get the `cluster1` controlplane IP and pass the `--server` option to `istioctl create-remote-secret`
647720
648721 ` ` ` sh
649722 CLUSTER2_CONTAINER_IP=$(kubectl get nodes -l node-role.kubernetes.io/control-plane --context "${CTX_CLUSTER2}" -o jsonpath='{.items[0].status.addresses[?(@.type == "InternalIP")].address}')
@@ -654,11 +727,18 @@ These installation instructions are adapted from: https://istio.io/latest/docs/s
654727 kubectl apply -f - --context "${CTX_CLUSTER1}"
655728 ` ` `
656729
657- 9. Deploy sample applications to `cluster1` .
730+ 11. Create sample application namespaces in each cluster .
658731
659732 ` ` ` sh
660733 kubectl get ns sample --context "${CTX_CLUSTER1}" || kubectl create --context="${CTX_CLUSTER1}" namespace sample
661734 kubectl label --context="${CTX_CLUSTER1}" namespace sample istio-injection=enabled
735+ kubectl get ns sample --context "${CTX_CLUSTER2}" || kubectl create --context="${CTX_CLUSTER2}" namespace sample
736+ kubectl label --context="${CTX_CLUSTER2}" namespace sample istio-injection=enabled
737+ ` ` `
738+
739+ 12. Deploy sample applications in `cluster1`.
740+
741+ ` ` ` sh
662742 kubectl apply --context="${CTX_CLUSTER1}" \
663743 -f https://raw.githubusercontent.com/istio/istio/${ISTIO_VERSION}/samples/helloworld/helloworld.yaml \
664744 -l service=helloworld -n sample
@@ -669,11 +749,9 @@ These installation instructions are adapted from: https://istio.io/latest/docs/s
669749 -f https://raw.githubusercontent.com/istio/istio/${ISTIO_VERSION}/samples/sleep/sleep.yaml -n sample
670750 ` ` `
671751
672- 10 . Deploy sample applications to `cluster2`.
752+ 13 . Deploy sample applications in `cluster2`.
673753
674754 ` ` ` sh
675- kubectl get ns sample --context "${CTX_CLUSTER2}" || kubectl create --context="${CTX_CLUSTER2}" namespace sample
676- kubectl label --context="${CTX_CLUSTER2}" namespace sample istio-injection=enabled
677755 kubectl apply --context="${CTX_CLUSTER2}" \
678756 -f https://raw.githubusercontent.com/istio/istio/${ISTIO_VERSION}/samples/helloworld/helloworld.yaml \
679757 -l service=helloworld -n sample
@@ -684,25 +762,37 @@ These installation instructions are adapted from: https://istio.io/latest/docs/s
684762 -f https://raw.githubusercontent.com/istio/istio/${ISTIO_VERSION}/samples/sleep/sleep.yaml -n sample
685763 ` ` `
686764
687- 11. Verify that you see a response from both v1 and v2.
765+ 14. Wait for the sample applications to be ready.
766+ ` ` ` sh
767+ kubectl --context="${CTX_CLUSTER1}" wait --for condition=available -n sample deployment/helloworld-v1
768+ kubectl --context="${CTX_CLUSTER2}" wait --for condition=available -n sample deployment/helloworld-v2
769+ kubectl --context="${CTX_CLUSTER1}" wait --for condition=available -n sample deployment/sleep
770+ kubectl --context="${CTX_CLUSTER2}" wait --for condition=available -n sample deployment/sleep
771+ ` ` `
772+
773+ 15. From `cluster1`, send 10 requests to the helloworld service. Verify that you see responses from both v1 and v2.
688774
689- ` cluster1` responds with v1 and v2
690775 ` ` ` sh
691- kubectl exec --context="${CTX_CLUSTER1}" -n sample -c sleep \
776+ for i in {0..9}; do
777+ kubectl exec --context="${CTX_CLUSTER1}" -n sample -c sleep \
692778 "$(kubectl get pod --context="${CTX_CLUSTER1}" -n sample -l \
693779 app=sleep -o jsonpath='{.items[0].metadata.name}')" \
694- -- curl -sS helloworld.sample:5000/hello
780+ -- curl -sS helloworld.sample:5000/hello;
781+ done
695782 ` ` `
696783
697- ` cluster2` responds with v1 and v2
784+ 16. From `cluster2`, send another 10 requests to the helloworld service. Verify that you see responses from both v1 and v2.
785+
698786 ` ` ` sh
699- kubectl exec --context="${CTX_CLUSTER2}" -n sample -c sleep \
787+ for i in {0..9}; do
788+ kubectl exec --context="${CTX_CLUSTER2}" -n sample -c sleep \
700789 "$(kubectl get pod --context="${CTX_CLUSTER2}" -n sample -l \
701790 app=sleep -o jsonpath='{.items[0].metadata.name}')" \
702- -- curl -sS helloworld.sample:5000/hello
791+ -- curl -sS helloworld.sample:5000/hello;
792+ done
703793 ` ` `
704794
705- 12 . Cleanup
795+ 17 . Cleanup
706796
707797 ` ` ` sh
708798 kubectl delete istios default --context="${CTX_CLUSTER1}"
0 commit comments