Configurare un mesh multi-cluster su Cloud Service Mesh gestito
Questa guida spiega come unire due cluster in un unico Cloud Service Mesh utilizzando Mesh CA o il servizio Certificate Authority e attivare il bilanciamento del carico tra cluster. Puoi estendere facilmente questa procedura per incorporare un numero qualsiasi di cluster nella tua mesh.
Una configurazione di Cloud Service Mesh multi-cluster può risolvere diversi scenari aziendali fondamentali, come scalabilità, posizione e isolamento. Per ulteriori informazioni, consulta Casi d'uso multi-cluster.
Prerequisiti
Questa guida presuppone che tu abbia due o più Google Cloud cluster GKE che soddisfano i seguenti requisiti:
- Cloud Service Mesh installato sui cluster. Devi avere
asmcli, lo strumentoistioctle i sample cheasmcliscarica nella directory specificata in--output_dir. - Prima di configurare Cloud Service Mesh, i cluster nel tuo mesh devono avere connettività tra tutti i pod. Inoltre, se unisci cluster che non fanno parte dello stesso progetto, questi devono essere registrati nello stesso progetto host del parco risorse e devono essere configurati in un VPC condiviso insieme sulla stessa rete. Ti consigliamo inoltre di avere un progetto per ospitare il VPC condiviso e due progetti di servizio per creare i cluster. Per maggiori informazioni, consulta Configurare i cluster con VPC condiviso.
- Se utilizzi Certificate Authority Service, tutti i cluster devono avere i rispettivi pool di CA subordinate collegati allo stesso pool di CA radice. In caso contrario, tutti dovranno utilizzare lo stesso pool di CA.
Impostazione di variabili di progetto e cluster
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 relativocontextnon sarà disponibile per l'utilizzo nei passaggi successivi di questa guida.I comandi dipendono dal tipo di cluster, regionale o zonale:
Regionale
gcloud container clusters get-credentials ${CLUSTER_1} --region ${LOCATION_1} gcloud container clusters get-credentials ${CLUSTER_2} --region ${LOCATION_2}A livello di zona
gcloud container clusters get-credentials ${CLUSTER_1} --zone ${LOCATION_1} gcloud container clusters get-credentials ${CLUSTER_2} --zone ${LOCATION_2}
Crea regola firewall
In alcuni casi, devi creare una regola firewall per consentire il traffico tra i cluster. Ad esempio, devi creare una regola firewall se:
- Utilizzi sottoreti diverse per i cluster nella tua mesh.
- 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 sottorete. Se la tua 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 i blocchi CIDR IP di origine e le porte di destinazione di tutto il trafico in entrata.
Le seguenti istruzioni consentono la comunicazione tra tutti i cluster del progetto o solo tra $CLUSTER_1 e $CLUSTER_2.
Raccogli informazioni sulla rete dei tuoi cluster.
Tutti i cluster del progetto
Se i cluster si trovano nello stesso progetto, puoi utilizzare il seguente comando per consentire la comunicazione tra tutti i cluster del 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_1e$CLUSTER_2e 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_NETWORKAutopilot
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
Attivare il rilevamento degli endpoint tra cluster pubblici o privati con l'API dichiarativa
L'abilitazione di Cloud Service Mesh gestito con l'API Fleet attiverà il rilevamento degli endpoint per questo cluster. Se hai eseguito il provisioning di Cloud Service Mesh gestito con uno strumento diverso, puoi attivare manualmente il rilevamento degli endpoint nei cluster pubblici o privati di un parco applicando la configurazione "multicluster_mode":"connected" nel configmap asm-options. I cluster con questa configurazione abilitata nello stesso parco risorse
avranno il rilevamento dei servizi tra cluster abilitato automaticamente tra di loro.
Questo è l'unico modo per configurare il rilevamento degli endpoint multi-cluster se hai l'implementazione del control plane gestito (TD) e il modo consigliato per configurarlo se hai l'implementazione gestita (Istiod).
Prima di procedere, devi aver creato una regola firewall.
Attiva
Se il configmap asm-options esiste già nel cluster, abilita il rilevamento degli endpoint per il cluster:
kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"connected"}}'
Se la configmap asm-options non esiste ancora nel tuo cluster, creala con i dati associati e abilita il rilevamento degli endpoint per il cluster:
kubectl --context ${CTX_1} create configmap asm-options -n istio-system --from-file <(echo '{"data":{"multicluster_mode":"connected"}}')
Disattiva
Disattiva il rilevamento degli endpoint per un cluster:
kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"manual"}}'
Se annulli la registrazione di un cluster dal parco risorse senza disattivare il rilevamento degli endpoint, i secret potrebbero rimanere nel cluster. Devi eliminare manualmente eventuali segreti rimanenti.
Esegui il seguente comando per trovare i secret che richiedono la pulizia:
kubectl get secrets -n istio-system -l istio.io/owned-by=mesh.googleapis.com,istio/multiCluster=trueElimina ogni secret:
kubectl delete secret SECRET_NAMERipeti questo passaggio per ogni segreto rimanente.
Verificare la connettività multi-cluster
Questa sezione spiega come eseguire il deployment dei servizi HelloWorld e Sleep di esempio
nel tuo ambiente multi-cluster per verificare il funzionamento del bilanciamento del carico tra i cluster.
Imposta la variabile per la directory dei sample
Vai alla posizione in cui è stato scaricato
asmclied esegui il seguente comando per impostareASM_VERSIONexport ASM_VERSION="$(./asmcli --version)"Imposta una cartella di lavoro per i sample che utilizzi per verificare il funzionamento del bilanciamento del carico tra cluster. I sample si trovano in una sottodirectory della directory
--output_dirspecificata nel comandoasmcli install. Nel seguente comando, sostituisciOUTPUT_DIRcon la directory specificata in--output_dir.export SAMPLES_DIR=OUTPUT_DIR/istio-${ASM_VERSION%+*}
Attiva l'iniezione di sidecar
Crea lo spazio dei nomi di esempio in ogni cluster.
for CTX in ${CTX_1} ${CTX_2} do kubectl create --context=${CTX} namespace sample doneAttiva lo spazio dei nomi per l'iniezione. I passaggi dipendono dall'implementazione del control plane.
Gestito (TD)
- Applica l'etichetta di inserimento predefinita allo spazio dei nomi:
for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio.io/rev- istio-injection=enabled --overwrite doneGestito (Istiod)
Consigliato:esegui il seguente comando per applicare l'etichetta di inserimento predefinita allo spazio dei nomi:
for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio.io/rev- istio-injection=enabled --overwrite doneSe sei già un utente con il piano di controllo Istiod gestito: consigliamo di utilizzare l'iniezione predefinita, ma è supportata anche l'iniezione basata su revisione. Segui le istruzioni riportate di seguito:
Esegui il comando seguente per individuare i canali di rilascio disponibili:
kubectl -n istio-system get controlplanerevisionL'output è simile al seguente:
NAME AGE asm-managed-rapid 6d7hNell'output, il valore nella colonna
NAMEè l'etichetta di revisione corrispondente al canale di rilascio disponibile per la versione di Cloud Service Mesh.Applica l'etichetta di revisione allo spazio dei nomi:
for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio-injection- istio.io/rev=REVISION_LABEL --overwrite done
Installa il servizio HelloWorld
Crea il servizio HelloWorld in entrambi i cluster:
kubectl create --context=${CTX_1} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n samplekubectl create --context=${CTX_2} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n sample
Esegui il deployment di HelloWorld v1 e v2 in ogni cluster
Esegui il deployment di
HelloWorld v1inCLUSTER_1e div2inCLUSTER_2, il che ti aiuterà in un secondo momento a verificare il bilanciamento del carico tra cluster:kubectl create --context=${CTX_1} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l version=v1 -n samplekubectl create --context=${CTX_2} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l version=v2 -n sampleVerifica che
HelloWorld v1ev2siano in esecuzione utilizzando i seguenti comandi. Verifica che l'output sia simile a quello mostrato.kubectl get pod --context=${CTX_1} -n sampleNAME READY STATUS RESTARTS AGE helloworld-v1-86f77cd7bd-cpxhv 2/2 Running 0 40s
kubectl get pod --context=${CTX_2} -n sampleNAME READY STATUS RESTARTS AGE helloworld-v2-758dd55874-6x4t8 2/2 Running 0 40s
Esegui il deployment del servizio Sleep
Esegui il deployment del servizio
Sleepin entrambi i cluster. Questo pod genera traffico di rete artificiale a scopo dimostrativo:for CTX in ${CTX_1} ${CTX_2} do kubectl apply --context=${CTX} \ -f ${SAMPLES_DIR}/samples/sleep/sleep.yaml -n sample doneAttendi l'avvio del servizio
Sleepin ogni cluster. Verifica che l'output sia simile a quello mostrato:kubectl get pod --context=${CTX_1} -n sample -l app=sleepNAME READY STATUS RESTARTS AGE sleep-754684654f-n6bzf 2/2 Running 0 5s
kubectl get pod --context=${CTX_2} -n sample -l app=sleepNAME 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 la presenza di risposte alternate della versione 1 e della versione 2:
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}')" \ -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'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}')" \ -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'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 Cloud Service Mesh multi-cluster bilanciato in base al carico.
Eliminazione 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}