Questa guida spiega come unire due cluster in un unico Anthos Service Mesh utilizzando Mesh CA o Istio CA e come abilitare il bilanciamento del carico tra cluster. Puoi estendere facilmente questo processo per incorporare un numero qualsiasi di cluster nel tuo mesh.
Una configurazione multi-cluster Anthos Service Mesh può risolvere diversi scenari aziendali cruciali, come scalabilità, località e isolamento. Per maggiori informazioni, consulta Casi d'uso multi-cluster. Inoltre, devi ottimizzare le applicazioni per ottenere il massimo da un mesh di servizi. Per ulteriori informazioni, consulta Preparazione di un'applicazione per Anthos Service Mesh.
Prerequisiti
Questa guida presuppone che tu disponga di due o più cluster Google Cloud GKE che soddisfano i seguenti requisiti:
- Anthos Service Mesh 1.6.8 o versioni successive installato sui cluster.
- Se i cluster si trovano nello stesso progetto, consulta la Panoramica dell'installazione per installare o eseguire l'upgrade dei cluster alla versione richiesta.
- Se i cluster si trovano in progetti diversi, consulta Installazione e migrazione di più progetti per installare o eseguire l'upgrade dei cluster alla versione richiesta.
- Se unisci cluster che non sono nello stesso progetto, devono essere installati utilizzando il profilo
asm-gcp-multiproject
e i cluster devono trovarsi insieme in una configurazione VPC condiviso sulla stessa rete. Inoltre, ti consigliamo di avere un progetto per l'hosting del VPC condiviso e due progetti di servizio per la creazione dei cluster. Per maggiori informazioni, consulta Configurazione dei cluster con un VPC condiviso. - Se utilizzi l'autorità di certificazione Istio, usa lo stesso certificato radice personalizzato per entrambi i cluster.
- Se Anthos Service Mesh è basato su cluster privati, ti consigliamo di creare una singola subnet nello stesso VPC. In caso contrario, devi assicurarti che:
- I piani di controllo possono raggiungere quelli del cluster privato remoto tramite gli IP privati del cluster.
- Puoi aggiungere gli intervalli IP dei piani di controllo per le chiamate alle reti autorizzate dei cluster privati remoti. Per maggiori informazioni, consulta Configurare il rilevamento degli endpoint tra cluster privati.
Impostazione delle variabili di progetto e cluster
Per praticità, imposta una cartella di lavoro. Questa è la cartella in cui hai scaricato ed estratto i file Anthos Service Mesh nel passaggio del prerequisito, Preparazione all'installazione di Anthos Service Mesh.
export PROJECT_DIR=YOUR_WORKING_FOLDER
Crea le seguenti variabili di ambiente per l'ID progetto, la zona o la regione del cluster, il nome del cluster e il contesto.
export PROJECT_1=PROJECT_ID_1 export LOCATION_1=CLUSTER_LOCATION_1 export CLUSTER_1=CLUSTER_NAME_1 export CTX_1="gke_${PROJECT_1}_${LOCATION_1}_${CLUSTER_1}" export PROJECT_2=PROJECT_ID_2 export LOCATION_2=CLUSTER_LOCATION_2 export CLUSTER_2=CLUSTER_NAME_2 export CTX_2="gke_${PROJECT_2}_${LOCATION_2}_${CLUSTER_2}"
Se si tratta di cluster appena creati, assicurati di recuperare le credenziali per ogni cluster con i seguenti comandi
gcloud
, altrimenti il clustercontext
associato non sarà disponibile per l'utilizzo nei passaggi successivi di questa guida:gcloud container clusters get-credentials ${CLUSTER_1} gcloud container clusters get-credentials ${CLUSTER_2}
Crea regola firewall
In alcuni casi, devi creare una regola firewall per consentire il traffico tra cluster. Ad esempio, devi creare una regola firewall se:
- Nella rete mesh utilizzi subnet diverse per i cluster.
- I pod aprono porte diverse da 443 e 15002.
GKE aggiunge automaticamente regole firewall a ciascun nodo per consentire il traffico all'interno della stessa subnet. Se la rete mesh contiene più subnet, devi configurare esplicitamente le regole firewall per consentire il traffico tra subnet. Devi aggiungere una nuova regola firewall per ogni subnet per consentire ai blocchi CIDR degli IP di origine e alla destinazione delle porte di tutto il traffico in entrata.
Le istruzioni seguenti consentono la comunicazione tra tutti i cluster nel progetto o solo tra $CLUSTER_1
e $CLUSTER_2
.
Raccogli informazioni sulla rete dei tuoi cluster.
Tutti i cluster di progetto
Se i cluster si trovano nello stesso progetto, puoi utilizzare il seguente comando per consentire la comunicazione tra tutti i cluster nel tuo progetto. Se nel progetto sono presenti cluster che non vuoi esporre, utilizza il comando nella scheda Cluster specifici.
function join_by { local IFS="$1"; shift; echo "$*"; } ALL_CLUSTER_CIDRS=$(gcloud container clusters list --project $PROJECT_1 --format='value(clusterIpv4Cidr)' | sort | uniq) ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}")) ALL_CLUSTER_NETTAGS=$(gcloud compute instances list --project $PROJECT_1 --format='value(tags.items.[0])' | sort | uniq) ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
Cluster specifici
Il seguente comando consente la comunicazione tra
$CLUSTER_1
e$CLUSTER_2
e non espone altri cluster nel progetto.function join_by { local IFS="$1"; shift; echo "$*"; } ALL_CLUSTER_CIDRS=$(for P in $PROJECT_1 $PROJECT_2; do gcloud --project $P container clusters list --filter="name:($CLUSTER_1,$CLUSTER_2)" --format='value(clusterIpv4Cidr)'; done | sort | uniq) ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}")) ALL_CLUSTER_NETTAGS=$(for P in $PROJECT_1 $PROJECT_2; do gcloud --project $P compute instances list --filter="name:($CLUSTER_1,$CLUSTER_2)" --format='value(tags.items.[0])' ; done | sort | uniq) ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
Crea la regola firewall.
GKE
gcloud compute firewall-rules create istio-multicluster-pods \ --allow=tcp,udp,icmp,esp,ah,sctp \ --direction=INGRESS \ --priority=900 \ --source-ranges="${ALL_CLUSTER_CIDRS}" \ --target-tags="${ALL_CLUSTER_NETTAGS}" --quiet \ --network=YOUR_NETWORK
Autopilot
TAGS="" for CLUSTER in ${CLUSTER_1} ${CLUSTER_2} do TAGS+=$(gcloud compute firewall-rules list --filter="Name:$CLUSTER*" --format="value(targetTags)" | uniq) && TAGS+="," done TAGS=${TAGS::-1} echo "Network tags for pod ranges are $TAGS" gcloud compute firewall-rules create asm-multicluster-pods \ --allow=tcp,udp,icmp,esp,ah,sctp \ --network=gke-cluster-vpc \ --direction=INGRESS \ --priority=900 --network=VPC_NAME \ --source-ranges="${ALL_CLUSTER_CIDRS}" \ --target-tags=$TAGS
Configura il rilevamento degli endpoint tra i cluster
Configura il rilevamento degli endpoint per il bilanciamento del carico tra cluster utilizzando i comandi seguenti. Questo passaggio esegue le seguenti attività:
- Il comando
istioctl
crea un secret che concede l'accesso al server API Kube per un cluster. - Il comando
kubectl
applica il secret a un altro cluster, in modo che il secondo cluster possa leggere gli endpoint di servizio dal primo.
istioctl x create-remote-secret --context=${CTX_1} --name=${CLUSTER_1} | \ kubectl apply -f - --context=${CTX_2}
istioctl x create-remote-secret --context=${CTX_2} --name=${CLUSTER_2} | \ kubectl apply -f - --context=${CTX_1}
Configura il rilevamento degli endpoint tra cluster privati
Quando utilizzi cluster privati, devi configurare gli IP privati dei cluster remoti anziché gli IP pubblici perché gli IP pubblici non sono accessibili.
Scrivi i secret con IP pubblici in file temporanei:
istioctl x create-remote-secret --context=${CTX_1} --name=${CLUSTER_1} > ${CTX_1}.secret
istioctl x create-remote-secret --context=${CTX_2} --name=${CLUSTER_2} > ${CTX_2}.secret
Recupera gli IP privati per i cluster privati e sostituisci gli IP pubblici con questi nei secret dei file temporanei:
PRIV_IP=`gcloud container clusters describe "${CLUSTER_1}" --project "${PROJECT_1}" \ --zone "${LOCATION_1}" --format "value(privateClusterConfig.privateEndpoint)"` ./istioctl x create-remote-secret --context=${CTX_1} --name=${CLUSTER_1} --server=https://${PRIV_IP} > ${CTX_1}.secret
PRIV_IP=`gcloud container clusters describe "${CLUSTER_2}" --project "${PROJECT_2}" \ --zone "${LOCATION_2}" --format "value(privateClusterConfig.privateEndpoint)"` ./istioctl x create-remote-secret --context=${CTX_2} --name=${CLUSTER_2} --server=https://${PRIV_IP} > ${CTX_2}.secret
Applica i nuovi secret nei cluster:
kubectl apply -f ${CTX_1}.secret --context=${CTX_2}
kubectl apply -f ${CTX_2}.secret --context=${CTX_1}
Configurazione delle reti autorizzate per i cluster privati
Segui questa sezione solo se tutte le condizioni seguenti si applicano al tuo mesh:
- Stai utilizzando cluster privati.
- I cluster non appartengono alla stessa subnet.
- I cluster hanno abilitato le reti autorizzate.
Quando esegui il deployment di più cluster in Anthos Service Mesh, l'elemento Istiod in ogni cluster deve chiamare il piano di controllo GKE dei cluster remoti. Per consentire il traffico, devi aggiungere l'intervallo di indirizzi dei pod nel cluster di chiamata alle reti autorizzate dei cluster remoti.
Ottieni il blocco CIDR IP del pod per ogni cluster:
POD_IP_CIDR_1=`gcloud container clusters describe ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1} \ --format "value(ipAllocationPolicy.clusterIpv4CidrBlock)"`
POD_IP_CIDR_2=`gcloud container clusters describe ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2} \ --format "value(ipAllocationPolicy.clusterIpv4CidrBlock)"`
Aggiungi i blocchi CIDR IP dei pod del cluster Kubernetes ai cluster remoti:
EXISTING_CIDR_1=`gcloud container clusters describe ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1} \ --format "value(masterAuthorizedNetworksConfig.cidrBlocks.cidrBlock)"` gcloud container clusters update ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1} \ --enable-master-authorized-networks \ --master-authorized-networks ${POD_IP_CIDR_2},${EXISTING_CIDR_1//;/,}
EXISTING_CIDR_2=`gcloud container clusters describe ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2} \ --format "value(masterAuthorizedNetworksConfig.cidrBlocks.cidrBlock)"` gcloud container clusters update ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2} \ --enable-master-authorized-networks \ --master-authorized-networks ${POD_IP_CIDR_1},${EXISTING_CIDR_2//;/,}
Per maggiori informazioni, consulta la sezione Creazione di un cluster con reti autorizzate.
Verifica che le reti autorizzate siano aggiornate:
gcloud container clusters describe ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1} \ --format "value(masterAuthorizedNetworksConfig.cidrBlocks.cidrBlock)"
gcloud container clusters describe ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2} \ --format "value(masterAuthorizedNetworksConfig.cidrBlocks.cidrBlock)"
Abilita accesso globale piano di controllo
Segui questa sezione solo se tutte le condizioni seguenti si applicano al tuo mesh:
- Stai utilizzando cluster privati.
- Puoi utilizzare regioni diverse per i cluster nel tuo mesh.
Devi abilitare l'accesso globale del piano di controllo per consentire a istiod
in ogni cluster di chiamare il piano di controllo GKE dei cluster remoti.
Abilita accesso globale piano di controllo:
gcloud container clusters update ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1} \ --enable-master-global-access
gcloud container clusters update ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2} \ --enable-master-global-access
Verifica che l'accesso globale al piano di controllo sia abilitato:
gcloud container clusters describe ${CLUSTER_1} --zone ${LOCATION_1}
gcloud container clusters describe ${CLUSTER_2} --zone ${LOCATION_2}
La sezione
privateClusterConfig
nell'output mostra lo stato dimasterGlobalAccessConfig
.
Verifica il deployment
Questa sezione spiega come eseguire il deployment di un servizio HelloWorld
di esempio nel tuo ambiente multi-cluster per verificare che il bilanciamento del carico tra cluster funzioni.
Attiva inserimento sidecar
Utilizza il seguente comando per individuare il valore dell'etichetta di revisione dal servizio
istiod
, che utilizzerai nei passaggi successivi.kubectl -n istio-system get pods -l app=istiod --show-labels
L'output è simile al seguente:
NAME READY STATUS RESTARTS AGE LABELS istiod-asm-173-3-5788d57586-bljj4 1/1 Running 0 23h app=istiod,istio.io/rev=asm-173-3,istio=istiod,pod-template-hash=5788d57586 istiod-asm-173-3-5788d57586-vsklm 1/1 Running 1 23h app=istiod,istio.io/rev=asm-173-3,istio=istiod,pod-template-hash=5788d57586
Nell'output, sotto la colonna
LABELS
, prendi nota del valore dell'etichetta di revisioneistiod
, che segue il prefissoistio.io/rev=
. In questo esempio, il valore èasm-173-3
. Utilizza il valore di revisione nei passaggi della sezione successiva.
Installa il servizio HelloWorld
Crea lo spazio dei nomi di esempio e la definizione del servizio in ogni cluster. Nel seguente comando, sostituisci REVISION con l'etichetta di revisione istiod
che hai annotato nel passaggio precedente.
for CTX in ${CTX_1} ${CTX_2} do kubectl create --context=${CTX} namespace sample kubectl label --context=${CTX} namespace sample \ istio-injection- istio.io/rev=REVISION --overwrite done
Sostituisci REVISION con l'etichetta di revisione istiod
che hai annotato in precedenza.
L'output è:
label "istio-injection" not found. namespace/sample labeled
Puoi ignorare label "istio-injection" not found.
Crea il servizio HelloWorld in entrambi i cluster:
kubectl create --context=${CTX_1} \ -f ${PROJECT_DIR}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n sample
kubectl create --context=${CTX_2} \ -f ${PROJECT_DIR}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n sample
Esegui il deployment di HelloWorld v1 e v2 in ciascun cluster
Esegui il deployment di
HelloWorld v1
inCLUSTER_1
e div2
inCLUSTER_2
, che consente in seguito di verificare il bilanciamento del carico tra cluster:kubectl create --context=${CTX_1} \ -f ${PROJECT_DIR}/samples/helloworld/helloworld.yaml \ -l version=v1 -n sample
kubectl create --context=${CTX_2} \ -f ${PROJECT_DIR}/samples/helloworld/helloworld.yaml \ -l version=v2 -n sample
Verifica che
HelloWorld v1
ev2
siano in esecuzione utilizzando i seguenti comandi. Verifica che l'output sia simile a quello mostrato:kubectl get pod --context=${CTX_1} -n sample
NAME READY STATUS RESTARTS AGE helloworld-v1-86f77cd7bd-cpxhv 2/2 Running 0 40s
kubectl get pod --context=${CTX_2} -n sample
NAME READY STATUS RESTARTS AGE helloworld-v2-758dd55874-6x4t8 2/2 Running 0 40s
Esegui il deployment del servizio Sleep
Esegui il deployment del servizio
Sleep
in entrambi i cluster. Questo pod genera traffico di rete artificiale a fini dimostrativi:for CTX in ${CTX_1} ${CTX_2} do kubectl apply --context=${CTX} \ -f ${PROJECT_DIR}/samples/sleep/sleep.yaml -n sample done
Attendi l'avvio del servizio
Sleep
in ogni cluster. Verifica che l'output sia simile a quello mostrato:kubectl get pod --context=${CTX_1} -n sample -l app=sleep
NAME READY STATUS RESTARTS AGE sleep-754684654f-n6bzf 2/2 Running 0 5s
kubectl get pod --context=${CTX_2} -n sample -l app=sleep
NAME READY STATUS RESTARTS AGE sleep-754684654f-dzl9j 2/2 Running 0 5s
Verifica il bilanciamento del carico tra cluster
Chiama il servizio HelloWorld
più volte e controlla l'output per verificare
le risposte alternative da v1 e v2:
Chiama il servizio
HelloWorld
:kubectl exec --context="${CTX_1}" -n sample -c sleep \ "$(kubectl get pod --context="${CTX_1}" -n sample -l \ app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -- curl -sS helloworld.sample:5000/hello
L'output è simile a quello mostrato:
Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ...
Chiama di nuovo il servizio
HelloWorld
:kubectl exec --context="${CTX_2}" -n sample -c sleep \ "$(kubectl get pod --context="${CTX_2}" -n sample -l \ app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -- curl -sS helloworld.sample:5000/hello
L'output è simile a quello mostrato:
Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ...
Congratulazioni, hai verificato il tuo Anthos Service Mesh multi-cluster con bilanciamento del carico.
Esegui la pulizia del servizio HelloWorld
Al termine della verifica del bilanciamento del carico, rimuovi il servizio HelloWorld
e Sleep
dal cluster.
kubectl delete ns sample --context ${CTX_1} kubectl delete ns sample --context ${CTX_2}