Configurazione di un mesh multi-cluster su GKE
Questa guida spiega come unire due cluster in un unico mesh di servizi Cloud utilizzando Mesh CA oppure Istio CA, 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 versione 1.11 o successive installata sui cluster che utilizzano
asmcli install
. Ti servonoasmcli
, lo strumentoistioctl
e gli esempi cheasmcli
scarica nell'app che hai specificato in--output_dir
quando hai eseguitoasmcli install
Se è necessario effettuare la configurazione, segui i passaggi Installa strumenti dipendenti e convalida il cluster a:I cluster nel tuo mesh devono avere connettività tra tutti i pod prima di configurare Cloud Service Mesh. 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 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 la CA Istio, utilizza lo stesso certificato radice personalizzato per entrambi i cluster.
Se Cloud Service Mesh è basato su cluster privati, ti consigliamo di creare una singola subnet nello stesso VPC, altrimenti devi assicurarti che:
- I piani di controllo possono raggiungere i piani di controllo del cluster privato remoto tramite IP privati del cluster.
- Puoi aggiungere gli intervalli IP dei control plane chiamanti alle reti autorizzate dei cluster privati remoti. Per ulteriori informazioni, vedi Configura il rilevamento degli endpoint tra cluster privati.
Il server API deve essere raggiungibile dalle altre istanze di Cloud Service Mesh nel piano di controllo multi-cluster.
- Assicurati che per i cluster sia attivo l'accesso globale.
- Assicurati che l'IP del piano di controllo di Cloud Service Mesh sia stato consentito correttamente tramite nella lista consentita con Rete autorizzata principale.
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 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, regionale o di 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 ciascun nodo per consentire il traffico all'interno della stessa sottorete. 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 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 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 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
I passaggi necessari per configurare il rilevamento degli endpoint dipendono dalla tua preferenza per utilizzare l'API dichiarativa nei cluster in un parco risorse o abilitalo manualmente cluster pubblici o cluster privati.
Configura il rilevamento degli endpoint tra cluster pubblici
Per configurare il rilevamento degli endpoint tra i cluster GKE, esegui
asmcli create-mesh
. Questo comando:
- Registra tutti i cluster nello stesso parco risorse.
- Configura il mesh in modo che l'identità dei carichi di lavoro del parco risorse sia attendibile.
- Crea secret remoti.
Puoi specificare l'URI per ciascun cluster o il percorso file kubeconfig.
URI cluster
Nel comando seguente, sostituisci FLEET_PROJECT_ID
con
l'ID progetto del progetto host del parco risorse e l'URI del cluster con
nome, zona o regione del cluster e ID progetto per ogni cluster.
Questo esempio mostra solo due cluster, ma puoi eseguire il comando per abilitare
il rilevamento degli endpoint su cluster aggiuntivi, in base alle
numero massimo consentito di cluster che puoi aggiungere al tuo parco risorse.
./asmcli create-mesh \
FLEET_PROJECT_ID \
${PROJECT_1}/${LOCATION_1}/${CLUSTER_1} \
${PROJECT_2}/${LOCATION_2}/${CLUSTER_2}
File kubeconfig
Nel comando seguente, sostituisci FLEET_PROJECT_ID
con
l'ID progetto del
progetto host del parco risorse
e PATH_TO_KUBECONFIG
con il percorso di ciascun
file kubeconfig
. Questo esempio mostra solo due cluster, ma puoi eseguire
per abilitare il rilevamento degli endpoint su cluster aggiuntivi, in base alle
numero massimo consentito di cluster che puoi aggiungere al tuo parco risorse.
./asmcli create-mesh \
FLEET_PROJECT_ID \
PATH_TO_KUBECONFIG_1 \
PATH_TO_KUBECONFIG_2
Configura il rilevamento degli endpoint tra cluster privati
Configura i secret remoti per consentire all'API server di accedere al cluster al piano di controllo Cloud Service Mesh dell'altro cluster. I comandi dipendono dal tipo di Cloud Service Mesh (in-cluster o gestito):
A. Per Cloud Service Mesh nel cluster, devi configurare gli IP privati di IP pubblici perché questi ultimi non sono accessibili:
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
B. Per Managed Cloud Service Mesh:
PUBLIC_IP=`gcloud container clusters describe "${CLUSTER_1}" --project "${PROJECT_1}" \ --zone "${LOCATION_1}" --format "value(privateClusterConfig.publicEndpoint)"` ./istioctl x create-remote-secret --context=${CTX_1} --name=${CLUSTER_1} --server=https://${PUBLIC_IP} > ${CTX_1}.secret
PUBLIC_IP=`gcloud container clusters describe "${CLUSTER_2}" --project "${PROJECT_2}" \ --zone "${LOCATION_2}" --format "value(privateClusterConfig.publicEndpoint)"` ./istioctl x create-remote-secret --context=${CTX_2} --name=${CLUSTER_2} --server=https://${PUBLIC_IP} > ${CTX_2}.secret
Applica i nuovi secret ai cluster:
kubectl apply -f ${CTX_1}.secret --context=${CTX_2}
kubectl apply -f ${CTX_2}.secret --context=${CTX_1}
Configura le reti autorizzate per i cluster privati
Segui questa sezione solo se al tuo mesh si applicano tutte le seguenti condizioni:
- Stai utilizzando cluster privati.
- I cluster non appartengono alla stessa subnet.
- I cluster hanno attivato le reti autorizzate.
Quando esegui il deployment di più cluster privati, il piano di controllo Cloud Service Mesh ogni cluster deve chiamare il piano di controllo GKE cluster remoti. Per consentire il traffico, devi aggiungere l'intervallo di indirizzi dei pod nella 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 degli 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 ulteriori informazioni, vedi 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 control plane
Segui questa sezione solo se al mesh si applicano tutte le seguenti condizioni:
- Stai utilizzando dei cluster privati.
- Utilizzi regioni diverse per i cluster nel mesh.
Devi abilitare l'accesso globale al piano di controllo per consentire al piano di controllo di Cloud Service Mesh in ciascun cluster di chiamare dal piano di controllo GKE dei cluster remoti.
Abilita l'accesso globale al 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} --project ${PROJECT_1} --zone ${LOCATION_1}
gcloud container clusters describe ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2}
La sezione
privateClusterConfig
nell'output mostra lo stato dimasterGlobalAccessConfig
.
Verificare la connettività multicluster
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 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 per i sample che utilizzi per verificare il funzionamento del 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 l'inserimento di file collaterali negli spazi dei nomi creati.
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 done
Ti consigliamo di utilizzare l'inserimento predefinito, ma è supportato anche l'inserimento basato sulle revisioni: segui le istruzioni riportate di seguito:
Usa questo comando per individuare l'etichetta di revisione su
istiod
:kubectl get deploy -n istio-system -l app=istiod -o \ jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
Applica l'etichetta di revisione allo spazio dei nomi. Nel seguente comando,
REVISION_LABEL
è il valore dell'etichetta della revisioneistiod
che hai annotato nel passaggio precedente.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
inCLUSTER_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 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 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 mesh di servizi Cloud multi-cluster con bilanciamento del carico.
Libera spazio nel 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}