Anthos Service Mesh (ASM) ist eine Managed-Installation von Istio, einem Service Mesh für Kubernetes. In dieser Schritt-für-Schritt-Anleitung zeigen wir, wie Sie ein Multi-Cluster-ASM mit Managed Control Plane aufsetzen.

Diese Anleitung führt Sie Schritt für Schritt durch das Setup eines Multi-Cluster-Anthos Service Mesh (ASM) mit Managed Control Plane.
Den passenden Code finden Sie hier: https://github.com/caddac/anthos-examples/tree/main/asm
Ein Service Mesh ist eine Abstraktionsschicht über verschiedenen Compute-Plattformen – in diesem Fall Clustern –, die die Kommunikation zwischen Services, Observability und Security vereinfacht. Diese Aufgaben wandern auf die Plattform, sodass die Anwendung selbst schlanker bleibt. In diesem Blogbeitrag rollen wir Anthos Service Mesh aus, eine Managed-Installation von Istio. Istio ist ein Service Mesh für Kubernetes – ein leistungsfähiges Tool, das konsistente Einblicke in Service-zu-Service-Observability und -Security liefert. Möglich wird das, weil Istio die gesamte Kommunikation zwischen Services über Proxys leitet, die als Sidecars neben Ihren Pods laufen.
Services nutzen die einheitlichen, transparenten Patterns von Istio, um mit anderen Services zu kommunizieren – ohne sich selbst darum kümmern zu müssen, wie sie einen anderen Service erreichen, wie sie eingehende Anfragen absichern oder wie sie Metriken zum Inter-Service-Traffic veröffentlichen. All das übernimmt Istio. In einem Multi-Cluster-Setup, in dem der operative Aufwand ohnehin höher ist, sind diese Funktionen umso wertvoller.
Ein Service Mesh hat allerdings auch Schattenseiten: höhere Setup-Komplexität, zusätzlicher Ressourcenbedarf und Kosten. Istio bringt viele Funktionen mit und lässt sich auf mehreren Wegen konfigurieren – über istioctl, IstioOperator und Helm. Anthos Service Mesh mit Managed Control Plane unterstützt jedoch weder die IstioOperator-API noch Helm.
In diesem Tutorial bauen wir zwei GKE-Cluster auf und rollen darauf die Istio-Hello-World-Anwendung aus. Anschließend richten wir auf nur einem der Cluster einen einzelnen Ingress ein und zeigen, dass der Traffic über die vier Hello-World-Pods auf beiden GKE-Clustern verteilt wird.

Terraform ausrollen
Aktualisieren Sie im Verzeichnis asm/infra die Werte in der Datei var_inputs.auto.tfvars.
Anschließend planen und anwenden:
$ terraform init
$ terraform apply
Hinweis: Falls das Apply fehlschlägt, starten Sie es einfach erneut. Terraform verhebt sich gelegentlich, wenn so viele voneinander abhängige Ressourcen auf einmal angelegt werden. Bei mir hat es drei Anläufe gebraucht, bis alle Ressourcen erstellt waren.
Hier passiert eine ganze Menge – schauen wir es uns kurz an.
Damit wird ein neues GCP-Projekt aufgesetzt und mehrere benötigte APIs aktiviert [1]. Kurzer Hinweis: In der offiziellen Doku fehlen offenbar die sts- und anthos-APIs – aktivieren Sie diese also unbedingt mit.
Außerdem werden eine VPC, zwei Subnetze mit Secondary Ranges sowie eine Firewall-Regel angelegt, damit alles miteinander kommunizieren kann. Zum Schluss wird das Hub-Mesh-Feature für das Projekt aktiviert.
Jede dieser Dateien legt einen Cluster an. Sie unterscheiden sich nur in den Cluster-Namen, Regionen und Subnet-Referenzen. Bei der Cluster-Konfiguration sind zwei Dinge erwähnenswert. Erstens haben wir das Label mesh_id gesetzt, damit GCP weiß, zu welchem Mesh dieser Cluster gehört. Zweitens haben wir Workload Identity aktiviert – so können Kubernetes-Service-Accounts als GCP-Service-Accounts agieren [2], ohne dass Sie JSON-Keys herunterladen oder überhaupt erstellen müssen.
Wir registrieren den Cluster im Fleet und nutzen den Cluster-Namen als Membership-ID.
Zum Schluss installieren wir die Managed Control Plane. Wir setzen auf die automatische Control Plane (also "managed") – aber welche Revision? Ein Blick auf das Revision-Label am Namespace verrät, welche Revision der Control Plane gerade aktiv ist [5]. Ja, so einfach ist das!
Damit haben wir zwei Cluster im selben Fleet, beide mit ASM und Managed Control Plane. Wir können also bereits Istio-Komponenten installieren – die clusterübergreifende Service Discovery funktioniert allerdings noch nicht.
Clusterübergreifende Service Discovery konfigurieren
Wir müssen für jeden Cluster Secrets auf allen anderen Clustern unseres Fleets installieren. Zum Glück gibt es dafür ein CLI-Tool: asmcli. Unter macOS funktioniert es leider noch nicht, daher führen wir es am einfachsten in der Cloud Shell aus.
Öffnen Sie die Cloud Shell in Ihrem Projekt, indem Sie zur GCP-Konsole wechseln und auf den Cloud-Shell-Button klicken.

Sobald sich die Konsole am unteren Bildschirmrand öffnet, führen Sie folgende Befehle aus:
$ curl https://storage.googleapis.com/csm-artifacts/asm/asmcli\_1.13 > asmcli
$ chmod +x asmcli
_$ ./asmcli create-mesh ${GOOGLE_CLOUD_PROJECT} _
_${GOOGLE_CLOUD_PROJECT}/us-west1/${GOOGLE_CLOUD_PROJECT}-cluster1 _
${GOOGLE_CLOUD_PROJECT}/us-east1/${GOOGLE_CLOUD_PROJECT}-cluster2

Kurzer Hinweis: Bei privaten Clustern sind zusätzliche Schritte nötig, um die clusterübergreifende Service Discovery zu aktivieren [6][7].
Apps und Istio-Komponenten ausrollen
Aus dem Verzeichnis asm/manifests können wir Apps installieren, um unser Mesh zu testen. Auf Cluster 1 spielen wir die helloworld-App und die Istio-Komponenten für den Ingress ein.
Holen Sie sich zunächst die Contexts für die Cluster:
export PROJECT_ID=<gcp_project_id>
gcloud container clusters get-credentials ${PROJECT_ID}-cluster1 --region us-west1 --project ${PROJECT_ID}
gcloud container clusters get-credentials ${PROJECT_ID}-cluster2 --region us-east1 --project ${PROJECT_ID}
Cluster 1 installieren:
kubectl apply -k manifests/ --context=gke_${PROJECT_ID}_us-west1_${PROJECT_ID}-cluster1
Und Cluster 2 installieren:
kubectl apply -k manifests/app/ --context=gke_${PROJECT_ID}_us-east1_${PROJECT_ID}-cluster2

Ergebnis prüfen
Nach wenigen Minuten sollte alles laufen, und Sie können sich Ihr Werk ansehen.
Prüfen Sie, ob die helloworld-Pods auf beiden Clustern laufen:
$ export PROJECT_ID=<gcp_project_id>
$ kubectl get pods -n helloworld
--context=gke_${PROJECT_ID}_us-west1_${PROJECT_ID}-cluster1
$ kubectl get pods -n helloworld
--context=gke_${PROJECT_ID}_us-east1_${PROJECT_ID}-cluster2

Prüfen Sie, ob das ingress-gateway-Deployment auf Cluster 1 läuft:
$ kubectl get deploy -n asm-gateways --context=gke_${PROJECT_ID}_us-west1_${PROJECT_ID}-cluster1

Prüfen Sie, ob der ingress-gateway-Service auf Cluster 1 eine externe IP hat:
$ kubectl get svc -n asm-gateways --context=gke_${PROJECT_ID}_us-west1_${PROJECT_ID}-cluster1

Prüfen Sie zum Schluss, ob das clusterübergreifende Load Balancing funktioniert, indem Sie den öffentlichen Endpoint mehrmals aufrufen. Sie werden sehen, dass sich Version und Pod-ID je nach getroffenem Pod ändern. Insgesamt sollten Sie 4 verschiedene Pod-IDs und 2 verschiedene Versionen erhalten.

$ curl /hello

Anpassen und Logs einsehen
Envoy-Debug-Logs aktivieren
Das haben wir bereits beim Ausrollen der ASM-Konfiguration eingerichtet. Werfen Sie einen Blick in die Datei asm/manifests/gateways/asm-config.yaml. Die ConfigMap, die wir ausgerollt haben, sorgt dafür, dass die Envoy-Proxys ihre Access-Logs nach stdout schreiben. Auf ähnliche Weise lassen sich weitere Optionen aktivieren [3].
Control-Plane-Logs
Auch bei einer Managed Control Plane haben Sie weiterhin Zugriff auf die Control-Plane-Logs. Sie finden sie im Logs Explorer unter der Ressource "Istio Control Plane".
Quellen
- https://cloud.google.com/service-mesh/docs/managed/auto-control-plane-with-fleet#before_you_begin
- https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity
- https://cloud.google.com/service-mesh/docs/managed/enable-managed-anthos-service-mesh-optional-features
- https://cloud.google.com/service-mesh/docs/managed/auto-control-plane-with-fleet
- https://cloud.google.com/service-mesh/docs/managed/select-a-release-channel#how_to_select_a_release_channel
- https://cloud.google.com/service-mesh/docs/unified-install/gke-install-multi-cluster#private-clusters-endpoint
- https://cloud.google.com/service-mesh/docs/unified-install/gke-install-multi-cluster#private-clusters-authorized-network