Configura un mesh multi-cluster su Cloud Service Mesh gestito
Questa guida spiega come unire due cluster in un unico mesh di servizi Cloud utilizzando Mesh CA oppure Certificate Authority Service e 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 Cloud Service Mesh può risolvere diverse fasi aziendali cruciali come la scalabilità, la posizione e l'isolamento. Per ulteriori informazioni, vedi Casi d'uso multi-cluster.
Prerequisiti
Questa guida presuppone che tu disponga di due o più Google Cloud di cluster GKE che soddisfano i seguenti requisiti:
- Cloud Service Mesh installato sui cluster. Ti servono
asmcli
, lo strumentoistioctl
e gli esempi cheasmcli
scarica nell'app che hai specificato in--output_dir
. - I cluster nel tuo mesh devono avere connettività tra tutti i pod prima di configurare Cloud Service Mesh. Inoltre, se unisci cluster che non si trovano nello stesso progetto, devono essere registrati nello stesso progetto host del parco risorse, e i cluster devono trovarsi in una configurazione VPC condivisa sulla stessa rete. Ti consigliamo inoltre di creare un progetto ospitare il VPC condiviso e due progetti di servizio per la creazione di cluster. Per maggiori informazioni le informazioni, vedi Configurazione di cluster con VPC condiviso
- Se utilizzi Certificate Authority Service, tutti i cluster devono avere la rispettiva catena di pool di CA subordinati nello stesso pool di CA radice. In caso contrario, dovranno utilizzare lo stesso pool di CA.
Impostazione delle variabili di progetto e cluster
Crea le seguenti variabili di ambiente per l'ID progetto e il cluster zona o regione, nome del cluster e 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 con i seguenti comandi
gcloud
, altrimenti sono associaticontext
non sarà disponibile per l'utilizzo nei passaggi successivi di questa guida.I comandi dipendono dal tipo di cluster, a livello di regione o zona:
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 l'accesso per via del traffico. Ad esempio, devi creare una regola firewall se:
- Puoi utilizzare subnet diverse per i cluster nella tua rete mesh.
- I pod aprono porte diverse da 443 e 15002.
GKE aggiunge automaticamente regole firewall a ogni nodo per 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 aggiungi una nuova regola firewall per ogni subnet per consentire i blocchi CIDR IP di origine e le porte di destinazione di tutte le per il traffico in entrata.
Le istruzioni seguenti consentono la comunicazione tra tutti i cluster nel tuo
progetto o solo tra $CLUSTER_1
e $CLUSTER_2
.
Raccogli informazioni sui cluster in ogni rete.
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 del progetto. Se ci sono nel progetto che non vuoi esporre, utilizza il comando la 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 tuo 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
Abilita il rilevamento degli endpoint tra cluster pubblici o privati con un'API dichiarativa
L'abilitazione di Cloud Service Mesh gestito con l'API del parco risorse abiliterà il rilevamento degli endpoint
per questo cluster. Se hai eseguito il provisioning di Cloud Service Mesh gestito con uno strumento diverso, puoi abilitare manualmente il rilevamento degli endpoint tra dispositivi pubblici
cluster privati in un parco risorse applicando la configurazione "multicluster_mode":"connected"
configmap asm-options
. Cluster con questa configurazione abilitata nello stesso parco risorse
Service Discovery tra cluster sarà automaticamente abilitato tra ogni
e l'altro.
Questo è l'unico modo per configurare il rilevamento degli endpoint multi-cluster se hai Implementazione del piano di controllo gestito (TD), e il metodo consigliato per configurarlo se hai l'implementazione Managed (Istiod).
Prima di procedere, devi avere ha creato una regola firewall.
Attiva
Se la configmap asm-options
esiste già nel tuo cluster, abilita
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 cluster:
crearlo con i dati associati e abilitare il rilevamento endpoint per
cluster:
kubectl --context ${CTX_1} create configmap asm-options -n istio-system --from-file <(echo '{"data":{"multicluster_mode":"connected"}}')
Disattiva
Disabilita 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 disabilitare il rilevamento degli endpoint, potrebbero rimanere nel cluster. Devi rimuovere manualmente eventuali elementi i tuoi segreti.
Esegui questo 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=true
Elimina ogni secret:
kubectl delete secret SECRET_NAME
Ripeti questo passaggio per ogni secret rimanente.
Verifica la connettività multi-cluster
Questa sezione spiega come eseguire il deployment dei servizi HelloWorld
e Sleep
di esempio
all'ambiente multi-cluster per verificare il carico tra cluster
l'equilibrio.
Imposta variabile per la directory di esempio
Vai alla posizione in cui è stato scaricato
asmcli
ed esegui questo comando per impostareASM_VERSION
export ASM_VERSION="$(./asmcli --version)"
Imposta una cartella di lavoro sugli esempi che utilizzi per verificare il bilanciamento del carico tra cluster. I campioni si trovano in nella directory
--output_dir
specificata nella directory Comandoasmcli install
. Nel comando seguente, modificaOUTPUT_DIR
alla directory specificata in--output_dir
.export SAMPLES_DIR=OUTPUT_DIR/istio-${ASM_VERSION%+*}
Attiva inserimento file collaterale
Crea lo spazio dei nomi di esempio in ogni cluster.
for CTX in ${CTX_1} ${CTX_2} do kubectl create --context=${CTX} namespace sample done
Abilita lo spazio dei nomi per l'inserimento. I passaggi dipendono dall'implementazione del piano di controllo.
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 done
Gestito (Istiod)
Consigliato: esegui questo 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 done
Se sei un utente esistente con il piano di controllo Managed Istiod: Ti consigliamo di usare l'inserimento predefinito, ma l'inserimento basato sulle revisioni supportati. Segui queste istruzioni:
Esegui questo comando per individuare i canali di rilascio disponibili:
kubectl -n istio-system get controlplanerevision
L'output è simile al seguente:
NAME AGE asm-managed-rapid 6d7h
Nell'output, il valore sotto la colonna
NAME
è l'etichetta di revisione che corrisponde 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 sample
kubectl 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 v1
inCLUSTER_1
e div2
suCLUSTER_2
, che consentono di verificare in un secondo momento il bilanciamento del carico tra cluster:kubectl create --context=${CTX_1} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l version=v1 -n sample
kubectl create --context=${CTX_2} \ -f ${SAMPLES_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 scopo dimostrativo:for CTX in ${CTX_1} ${CTX_2} do kubectl apply --context=${CTX} \ -f ${SAMPLES_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 più volte il servizio HelloWorld
e controlla l'output per verificare
risposte alternate da v1 a 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}')" \ -- /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 mesh di servizi Cloud multi-cluster con bilanciamento del carico.
Libera spazio nel servizio HelloWorld
Al termine della verifica del bilanciamento del carico, rimuovi HelloWorld
e Sleep
dal tuo cluster.
kubectl delete ns sample --context ${CTX_1} kubectl delete ns sample --context ${CTX_2}