Multi-Cluster-Mesh-Netzwerk in GKE einrichten
In dieser Anleitung wird erläutert, wie Sie zwei Cluster mit Mesh CA oder Istio CA zu einem einzigen Cloud Service Mesh zusammenführen und das clusterübergreifende Load-Balancing aktivieren. Sie können diesen Prozess problemlos erweitern, um eine beliebige Anzahl von Clustern in Ihr Mesh-Netzwerk einzubinden.
Eine Cloud Service Mesh-Konfiguration mit mehreren Clustern kann in mehreren wichtigen Unternehmensszenarien wie Skalierung, Standortwahl und Isolation eine Lösung sein. Weitere Informationen finden Sie unter Multi-Cluster-Anwendungsfälle.
Vorbereitung
In dieser Anleitung wird davon ausgegangen, dass Sie mindestens zwei Google Cloud GKE-Cluster haben, die folgende Anforderungen erfüllen:
Cloud Service Mesh Version 1.11 oder höher wurde in den Clustern mit
asmcli installinstalliert. Sie benötigenasmcli, dasistioctlTool und Beispiele, dieasmcliin das Verzeichnis herunterlädt, das Sie bei der Ausführung vonasmcli installin--output_dirangegeben haben. Wenn Sie die Einrichtung vornehmen müssen, führen Sie die Schritte unter Abhängige Tools installieren und Cluster validieren aus, um Folgendes zu tun:In Clustern in Ihrem Mesh muss eine Verbindung zwischen allen Pods bestehen, bevor Sie Cloud Service Mesh konfigurieren. Wenn Sie Cluster zusammenführen, die sich nicht in demselben Projekt befinden, müssen sie im selben Hostprojekt der Flotte registriert sein und die Cluster müssen sich zusammen in einer Konfiguration mit gemeinsam genutzter VPC im selben Netzwerk befinden. Außerdem empfehlen wir, dass Sie ein Projekt zum Hosten der gemeinsam genutzten VPC und zwei Dienstprojekte zum Erstellen von Clustern haben. Weitere Informationen finden Sie unter Cluster mit gemeinsam genutzter VPC einrichten.
Wenn Sie die Istio-Zertifizierungsstelle nutzen, verwenden Sie für beide Cluster dasselbe benutzerdefinierte Root-Zertifikat.
Wenn Ihr Cloud Service Mesh auf privaten Clustern basiert, empfehlen wir das Erstellen eines einzelnen Subnetzes in derselben VPC. Andernfalls muss Folgendes gewährleistet sein:
- Die Steuerungsebenen können die Steuerungsebenen für private Remote-Cluster über die privaten IP-Adressen von Clustern erreichen.
- Sie können den autorisierten Netzwerken der privaten Remote-Cluster IP-Adressbereiche der aufrufenden Steuerungsebenen hinzufügen. Weitere Informationen finden Sie unter Endpunkterkennung zwischen privaten Clustern konfigurieren.
Der API-Server muss von den anderen Instanzen der Cloud Service Mesh-Steuerungsebene im Multi-Cluster-Mesh aus erreichbar sein.
- Für die Cluster muss der globale Zugriff aktiviert sein.
- Prüfen Sie, ob die IP-Adresse der Cloud Service Mesh-Steuerungsebene über die Zulassungsliste des autorisierten Master-Netzwerksordnungsgemäß zugelassen wurde.
Projekt- und Clustervariablen festlegen
Erstellen Sie die folgenden Umgebungsvariablen für die Projekt-ID, die Clusterzone oder -region, den Clusternamen und den Kontext.
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}"Wenn es sich um neu erstellte Cluster handelt, müssen Sie mit den folgenden
gcloud-Befehlen Anmeldedaten für jeden Cluster abrufen. Andernfalls ist der zugehörigecontextnicht für die nächsten Schritte dieser Anleitung verfügbar.Die Befehle hängen vom Clustertyp ab und sind entweder regional oder zonal:
Regional
gcloud container clusters get-credentials ${CLUSTER_1} --region ${LOCATION_1} gcloud container clusters get-credentials ${CLUSTER_2} --region ${LOCATION_2}Zonal
gcloud container clusters get-credentials ${CLUSTER_1} --zone ${LOCATION_1} gcloud container clusters get-credentials ${CLUSTER_2} --zone ${LOCATION_2}
Firewallregel erstellen
In einigen Fällen müssen Sie eine Firewallregel erstellen, um clusterübergreifenden Traffic zuzulassen. In folgenden Fällen müssen Sie beispielsweise eine Firewallregel erstellen:
- Sie verwenden unterschiedliche Subnetze für die Cluster in Ihrem Mesh-Netzwerk.
- Ihre Pods öffnen andere Ports als 443 und 15002.
GKE fügt jedem Knoten automatisch Firewallregeln hinzu, die Traffic innerhalb desselben Subnetzes zulassen. Wenn Ihr Mesh-Netzwerk mehrere Subnetze enthält, müssen Sie die Firewallregeln explizit so einrichten, dass subnetzübergreifender Traffic zulässig ist. Sie müssen dabei für jedes Subnetz eine neue Firewallregel hinzufügen, die die CIDR-Blöcke der Quell-IP-Adresse und die Zielports des gesamten eingehenden Traffics zulässt.
Die folgende Anleitung ermöglicht die Kommunikation zwischen allen Clustern in Ihrem Projekt oder nur zwischen $CLUSTER_1 und $CLUSTER_2.
Erfassen Sie Informationen zum Netzwerk Ihres Clusters.
Alle Projektcluster
Wenn sich die Cluster im selben Projekt befinden, können Sie den folgenden Befehl verwenden, um die Kommunikation zwischen allen Clustern in Ihrem Projekt zuzulassen. Wenn in Ihrem Projekt Cluster enthalten sind, die Sie nicht verfügbar machen möchten, verwenden Sie den Befehl auf dem Tab Bestimmte Cluster.
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}"))Bestimmte Cluster
Der folgende Befehl ermöglicht die Kommunikation zwischen
$CLUSTER_1und$CLUSTER_2und macht keine anderen Cluster in Ihrem Projekt verfügbar.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}"))Firewallregel erstellen
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
Endpunkterkennung konfigurieren
Die Schritte, die zum Konfigurieren der Endpunkterkennung erforderlich sind, hängen davon ab, ob Sie es vorziehen, die deklarative API clusterübergreifend in einer Flotte zu verwenden oder sie manuell in öffentlichen Clustern oder privaten Clustern zu aktivieren.
Endpunkterkennung zwischen öffentlichen Clustern konfigurieren
Zum Konfigurieren der Endpunkterkennung zwischen GKE-Clustern führen Sie asmcli create-mesh aus. Dieser Befehl:
- Registriert alle Cluster in derselben Flotte
- Konfiguriert das Mesh-Netzwerk so, dass der Workload Identity der Flotte vertraut wird
- Erstellt Remote-Secrets
Sie können entweder den URI für jeden Cluster oder den Pfad zur kubeconfig-Datei angeben.
Cluster-URI
Ersetzen Sie im folgenden Befehl FLEET_PROJECT_ID durch die Projekt-ID des Flottenhostprojekts und den Cluster-URI durch den Clusternamen, die Zone oder Region und die Projekt-ID für jeden Cluster.
In diesem Beispiel werden nur zwei Cluster gezeigt. Sie können jedoch den Befehl ausführen, um die Endpunkterkennung auf zusätzlichen Clustern zu aktivieren. Dabei gilt die maximal zulässige Anzahl von Clustern, die Sie Ihrer Flotte hinzufügen können..
./asmcli create-mesh \
FLEET_PROJECT_ID \
${PROJECT_1}/${LOCATION_1}/${CLUSTER_1} \
${PROJECT_2}/${LOCATION_2}/${CLUSTER_2}
kubeconfig-Datei
Ersetzen Sie im folgenden Befehl FLEET_PROJECT_ID durch die Projekt-ID des Flottenhostprojekts und PATH_TO_KUBECONFIG durch den Pfad zu jeder kubeconfig-Datei. In diesem Beispiel werden nur zwei Cluster gezeigt. Sie können jedoch den Befehl ausführen, um die Endpunkterkennung auf zusätzlichen Clustern zu aktivieren. Dabei gilt die maximal zulässige Anzahl von Clustern, die Sie Ihrer Flotte hinzufügen können.
./asmcli create-mesh \
FLEET_PROJECT_ID \
PATH_TO_KUBECONFIG_1 \
PATH_TO_KUBECONFIG_2
Endpunkterkennung zwischen privaten Clustern konfigurieren
Konfigurieren Sie Remote-Secrets, um dem API-Server Zugriff auf die Cloud Service Mesh-Steuerungsebene des anderen Clusters zu gewähren. Die Befehle hängen vom Cloud Service Mesh-Typ ab (clusterintern oder verwaltet):
A. Bei clusterinternem Cloud Service Mesh müssen Sie die privaten IP-Adressen anstelle der öffentlichen IP-Adressen konfigurieren, da nicht auf die öffentlichen IP-Adressen zugegriffen werden kann:
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}.secretPRIV_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}.secretB. Für verwaltetes 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}.secretPUBLIC_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}.secretWenden Sie die neuen Secrets auf die Cluster an:
kubectl apply -f ${CTX_1}.secret --context=${CTX_2}kubectl apply -f ${CTX_2}.secret --context=${CTX_1}
Autorisierte Netzwerke für private Cluster konfigurieren
Führen Sie die Schritte dieses Abschnitts nur aus, wenn die folgenden Bedingungen für Ihr Mesh-Netzwerk zutreffen:
- Sie verwenden private Cluster.
- Die Cluster gehören nicht zum selben Subnetz.
- Für die Cluster sind autorisierte Netzwerke aktiviert.
Wenn Sie mehrere private Cluster bereitstellen, muss die Cloud Service Mesh-Steuerungsebene in jedem Cluster die GKE-Steuerungsebene der Remote-Cluster aufrufen. Um Traffic zuzulassen, müssen Sie den autorisierten Netzwerken der Remote-Cluster den Pod-Adressbereich im aufrufenden Cluster hinzufügen.
Rufen Sie den CIDR-Block des Pod-IP-Adressbereichs für jeden Cluster ab:
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)"`Fügen Sie den Remote-Clustern die CIDR-Blöcke des Pod-IP-Adressbereichs im Kubernetes-Clusters hinzu:
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//;/,}Weitere Informationen finden Sie unter Cluster mit autorisierten Netzwerken erstellen.
Prüfen Sie, ob die autorisierten Netzwerke aktualisiert wurden:
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)"
Globalen Zugriff auf Steuerungsebene aktivieren
Führen Sie die Schritte dieses Abschnitts nur aus, wenn die folgenden Bedingungen für Ihr Mesh-Netzwerk zutreffen:
- Sie verwenden private Cluster.
- Sie verwenden unterschiedliche Subnetze für die Cluster in Ihrem Mesh-Netzwerk.
Globalen Zugriff auf Steuerungsebene aktivieren
gcloud container clusters update ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1} \ --enable-master-global-accessgcloud container clusters update ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2} \ --enable-master-global-accessPrüfen Sie, ob der globale Zugriff auf die Steuerungsebene aktiviert ist:
gcloud container clusters describe ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1}gcloud container clusters describe ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2}Im Abschnitt
privateClusterConfigwird in der Ausgabe der StatusmasterGlobalAccessConfigangezeigt.
Multicluster-Konnektivität prüfen
In diesem Abschnitt wird erläutert, wie Sie die Beispieldienste HelloWorld und Sleep in Ihrer Multi-Cluster-Umgebung bereitstellen, um zu überprüfen, ob das clusterübergreifende Load-Balancing funktioniert.
Variable für Beispielverzeichnis festlegen
Gehen Sie zu dem Speicherort, an dem
asmcliheruntergeladen wurde, und führen Sie den folgenden Befehl aus, umASM_VERSIONfestzulegen:export ASM_VERSION="$(./asmcli --version)"Legen Sie einen Arbeitsordner für die Beispiele fest, mit denen Sie prüfen, ob das clusterübergreifende Load-Balancing funktioniert. Die Beispiele befinden sich in einem Unterverzeichnis im Verzeichnis
--output_dir, das Sie im Befehlasmcli installangegeben haben. Ändern Sie im folgenden BefehlOUTPUT_DIRin das Verzeichnis, das Sie in--output_dirangegeben haben.export SAMPLES_DIR=OUTPUT_DIR/istio-${ASM_VERSION%+*}
Sidecar-Injektion aktivieren
Erstellen Sie den Beispiel-Namespace in jedem Cluster.
for CTX in ${CTX_1} ${CTX_2} do kubectl create --context=${CTX} namespace sample doneAktivieren Sie die Sidecar-Injektion für die erstellten Namespaces.
Empfohlen:Führen Sie den folgenden Befehl aus, um das Standard-Injektionslabel auf den Namespace anzuwenden:
for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio.io/rev- istio-injection=enabled --overwrite doneWir empfehlen die Standardeinschleusung. Die versionsbasierte Einschleusung wird jedoch auch unterstützt. Gehen Sie so vor:
Verwenden Sie den folgenden Befehl, um das Versionslabel für
istiodzu finden:kubectl get deploy -n istio-system -l app=istiod -o \ jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'Wenden Sie das Überarbeitungslabel auf den Namespace an. Im folgenden Befehl ist
REVISION_LABELder Wert desistiod-Überarbeitungslabels, den Sie im vorherigen Schritt notiert haben.for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio-injection- istio.io/rev=REVISION_LABEL --overwrite done
HelloWorld-Dienst installieren
Erstellen Sie in beiden Clustern den HelloWorld-Dienst:
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
HelloWorld v1 und v2 in jedem Cluster bereitstellen
Stellen Sie
HelloWorld v1inCLUSTER_1undv2inCLUSTER_2bereit. Das erleichtert später die Prüfung des clusterübergreifenden Load-Balancings.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 samplePrüfen Sie mit den folgenden Befehlen, ob
HelloWorld v1undv2ausgeführt werden. Prüfen Sie, ob die Ausgabe in etwa so aussieht: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
Sleep-Dienst bereitstellen
Stellen Sie den
Sleep-Dienst in beiden Clustern bereit. Dieser Pod generiert künstlichen Netzwerktraffic zur Veranschaulichung:for CTX in ${CTX_1} ${CTX_2} do kubectl apply --context=${CTX} \ -f ${SAMPLES_DIR}/samples/sleep/sleep.yaml -n sample doneWarten Sie, bis der
Sleep-Dienst in jedem Cluster gestartet wurde. Prüfen Sie, ob die Ausgabe in etwa so aussieht: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
Clusterübergreifendes Load-Balancing prüfen
Rufen Sie den HelloWorld-Dienst mehrmals auf und prüfen Sie die Ausgabe, um abwechselnde Antworten von v1 und v2 zu prüfen:
Rufen Sie den Dienst
HelloWorldauf: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'Die Ausgabe sollte in etwa so aussehen:
Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ...
Rufen Sie den Dienst
HelloWorldnoch einmal auf: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'Die Ausgabe sollte in etwa so aussehen:
Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ...
Sie haben Ihr Cloud Service Mesh mit Load-Balancing und mehreren Clustern erfolgreich geprüft.
HelloWorld-Dienst bereinigen
Entfernen Sie nach der Prüfung des Load-Balancings die Dienste HelloWorld und Sleep aus dem Cluster.
kubectl delete ns sample --context ${CTX_1}
kubectl delete ns sample --context ${CTX_2}