Dies ist die Fortsetzung meines vorherigen Blogbeitrags, in dem ich meine Einschätzung zu Istio Ambient Mesh geteilt und es mit dem klassischen, sidecar-basierten Data-Plane-Modell verglichen habe.
In diesem Artikel zeige ich Ihnen, wie Sie Istio Ambient Mesh auf einem Google Kubernetes Engine-Cluster auf der Google Cloud Platform installieren und nutzen.
Hinweis: Istio Ambient Mesh befindet sich noch im Alpha-Stadium und sollte erst dann in Produktivumgebungen eingesetzt werden, wenn der Status General Availability (GA) erreicht ist.
Voraussetzungen
- Auf dem Cluster muss eine unterstützte Kubernetes-Version laufen (1.25, 1.26, 1.27, 1.28, 1.29).
- CNI (Container Network Interface) muss im Cluster aktiviert sein. Bei GKE-Clustern ist GKE CNI standardmäßig aktiv. Dataplane v2 wird derzeit nicht unterstützt.
- Mindestens 3 Nodes mit jeweils 4 vCPU. Jeder z-tunnel reserviert 500 mCPU und 2 Gi Arbeitsspeicher – ohne die übrigen Komponenten. Sorgen Sie also für ausreichend vCPU und Speicher.
- Plattform-Voraussetzungen
- GKE-spezifische Voraussetzungen
Hinweis: Auf GKE-Autopilot-Clustern funktioniert diese Installation nicht, da Dataplane v2 dort nicht abwählbar ist. Sie können jedoch die Capabilities NET_ADMIN und NET_RAW aktivieren.
Wichtig: Kompatibilitätsprobleme mit DataPlane v2
Istio Ambient Mesh setzt das Istio-CNI-Plugin voraus. Es übernimmt die Aufgabe des istio-init-Containers (der die Capabilities NET_ADMIN und NET_RAW benötigt), ohne dass die Anwender für das Deployment erweiterte RBAC-Berechtigungen für solch privilegierte Container brauchen.
Die Istio-CNI-Dokumentation enthält folgenden Hinweis:
Hinweis: Das Istio-CNI-Plugin arbeitet als verkettetes CNI-Plugin und ist dafür ausgelegt, mit einem weiteren CNI-Plugin wie PTP oder Calico kombiniert zu werden. Details finden Sie unter Kompatibilität mit anderen CNI-Plugins.
Und genau hier wird es etwas knifflig. Die klassische GKE Data Plane (derzeit Standard) nutzt GKE CNI (bzw. Calico CNI, sofern Network Policy aktiviert ist) und stützt sich für das Routing innerhalb des Clusters auf kube-proxies und iptables.
Die relativ neue GKE Data Plane v2 (die künftig der Standard und damit De-facto-Standard sein wird) ist im Kern eine Managed-Variante von Cilium CNI, die mit einer eBPF Data Plane arbeitet und die kube-proxies durch moderne eBPF-Programme für ein leistungsfähigeres Networking ersetzt.
Dieser Artikel von Solo.io beschreibt, wie sich Cilium CNI so konfigurieren lässt, dass Istio nicht beeinträchtigt wird. Das gilt allerdings nur für das Sidecar-Modell von Istio – mit Dataplane V2 funktioniert es ohnehin nicht, da es sich um eine GCP-managed Komponente mit unveränderlicher Konfiguration handelt.
DataPlane V2 verwendet zwar ein veth-Device, doch möglicherweise vertragen sich die eBPF-Programme schlicht nicht miteinander. Falls Sie den genauen Grund kennen, freue ich mich über einen Kommentar.

Wir müssen Dataplane v2 in unserem Setup also deaktivieren, damit die Istio-CNI-Komponente erfolgreich installiert werden kann.
Ich hoffe, dass Dataplane v2 künftig unterstützt wird, denn in naher Zukunft wird es der Standard-Data-Plane-Modus für GKE-Cluster sein.
Cluster einrichten
In diesem Beispiel erstelle ich einen einfachen GKE-Cluster mit privaten Nodes und einem öffentlichen Master-Endpoint.
Hier der Befehl, mit dem ich den Cluster im Default-VPC bereitstelle. Die Variablen können Sie nach Belieben anpassen – achten Sie aber darauf, dass Dataplane v2 deaktiviert ist.
Im Produktivbetrieb empfiehlt es sich, größere Nodes mit vielen Pods pro Node zu verwenden, um das Setup voll auszureizen.
export PROJECT_ID=`gcloud config get-value project` && \
export M_TYPE=e2-standard-4 && \
export ZONE=us-central1-a && \
export CLUSTER_NAME=ambient-mesh-cluster && \
gcloud services enable container.googleapis.com && \
gcloud container clusters create $CLUSTER_NAME \
--project $PROJECT_ID \
--cluster-version "latest" \
--release-channel "regular" \
--location $ZONE \
--machine-type $M_TYPE \
--image-type "COS_CONTAINERD" \
--num-nodes "3" \
--enable-private-nodes \
--master-ipv4-cidr "172.16.0.0/28" \
--enable-ip-alias \
--no-enable-master-authorized-networks \
--network "projects/$PROJECT_ID/global/networks/default" \
--subnetwork "projects/$PROJECT_ID/regions/us-central1/subnetworks/default"
Sobald der Cluster steht, legt GCP automatisch Firewall-Regeln an, damit der Control-Plane-Master mit den Nodes kommunizieren kann.

Wie zu sehen ist, sind die TCP-Ports 443 (HTTPS) und 10250 (Kubelet) freigegeben. Diese Regel öffnet jedoch nicht Port 15017, den der Discovery-Validation-Webhook von Pilot (der Istio-Control-Plane-Komponente) benötigt.
Wer – wie hier – einen privaten GKE-Cluster nutzt, muss eine Firewall-Regel anlegen, die Traffic vom Master über Port 15017 erlaubt. Ermitteln Sie zunächst den Source-IP-Bereich des Masters und die Network-Tags der Firewall-Regel:
gcloud compute firewall-rules list --filter="name~gke-${CLUSTER_NAME}-[0-9a-z]*-master" --format="table(targetTags, sourceRanges.list())"
Erstellen Sie anschließend mit dem Source-IP-Bereich und den Network-Tags aus der Ausgabe des vorherigen Befehls eine neue Firewall-Regel, die Traffic vom Master über TCP-Port 15017 zulässt:
gcloud compute firewall-rules create <firewall-rule-name> --network <VPC-name> --source-ranges=<CIDR_RANGE> --direction=INGRESS --target-tags=<TAG> --allow tcp:15017
Stellen Sie außerdem sicher, dass im VPC, in dem der Cluster bereitgestellt ist, Cloud NAT konfiguriert ist, damit die Pods auf den privaten GKE-Nodes Internetzugriff haben.
Istio im Ambient-Modus herunterladen und installieren
Laden Sie die neueste Version von Istio herunter:
curl -L https://istio.io/downloadIstio | sh -
Wechseln Sie in das Istio-Verzeichnis und nehmen Sie den Istioctl-Client in Ihren Pfad auf:
cd istio-1.20.3/
export PATH=$PWD/bin:$PATH
Authentifizieren Sie sich und verbinden Sie sich mit Ihrem GKE-Cluster (achten Sie auf ausreichende IAM-Berechtigungen, um sich mit dem Cluster zu verbinden und Deployments durchzuführen):
gcloud container clusters get-credentials ${CLUSTER_NAME} --zone ${ZONE} --project ${PROJECT_ID}
Installieren Sie die Kubernetes-Gateway-CRDs:
$ kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
{ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v1.0.0" | kubectl apply -f -; }
Installieren Sie Istio im Ambient-Modus:
istioctl install --set profile=ambient --set "components.ingressGateways[0].enabled=true" --set "components.ingressGateways[0].name=istio-ingressgateway" --skip-confirmation
Anschließend sollten die folgenden 5 Komponenten erfolgreich installiert sein – allen voran das CNI und der z-tunnel.

Prüfen Sie über die Pods und DaemonSets im Namespace istio-system, ob die Komponenten installiert und einsatzbereit sind.

kubectl get pod -n istio-system

kubectl get ds -n istio-system

kubectl get ds -n kube-system
Anwendungen in Istio Ambient Mesh ausrollen
Das Schöne an Istio: Sie müssen Ihre Anwendungen nicht anpassen. Wir rollen hier die klassische Istio-Beispielanwendung Bookinfo unverändert aus und nehmen sie erst nach dem Deployment ins Mesh auf.
Den Code für die Bookinfo-Anwendung finden Sie im selben Verzeichnis, in dem Sie Istio installiert haben.
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
Rollen Sie zwei weitere Anwendungen (curl-Clients) aus, mit denen wir Traffic in der Mesh-Umgebung simulieren.
kubectl apply -f samples/sleep/sleep.yaml
kubectl apply -f samples/sleep/notsleep.yaml
Stellen Sie ein Ingress Gateway bereit, um aus dem Internet auf die Bookinfo-App zuzugreifen.
kubectl apply -export GATEWAY_HOST=$(kubectl get service/istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}' -n istio-system)l
Ermitteln Sie die internen und externen Endpoints des istio-ingressgateway-Service. Wir senden an beide Endpoints Traffic, um sowohl den Verkehr innerhalb des Mesh als auch externen Traffic von außerhalb des Clusters zu beobachten.
export GATEWAY_HOST_EXT=$(kubectl get service/istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}' -n istio-system)
export GATEWAY_HOST_INT=istio-ingressgateway.istio-system

aus Sicht des Browsers
Das Mesh in Aktion
Rollen Sie eine Beispielinstallation von Prometheus und Kiali aus, um den Traffic zu überwachen bzw. zu visualisieren.
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/prometheus.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/kiali.yaml
Passen Sie die Kiali-Service-Datei so an, dass der Service ins Internet exponiert wird und Sie ihn im Browser aufrufen können.
kubectl patch svc kiali -n istio-system -p '{"spec": {"type": "LoadBalancer"}}'
Sobald für den Kiali-Service eine externe IP bereitsteht, können Sie die Oberfläche im Browser öffnen. Aktuell sehen wir nur wenige Daten, da unsere Anwendungen noch nicht Teil des Mesh sind.

Nehmen Sie die Bookinfo-Anwendungen im Default-Namespace ins Ambient Mesh auf, indem Sie den Namespace entsprechend labeln.
kubectl label namespace default istio.io/dataplane-mode=ambient
Die Anwendungen sind nun nahtlos Teil des Mesh – ohne jegliche Unterbrechung. Schicken wir nun etwas Traffic von unseren curl-Clients an diese Anwendungen und sehen das Mesh in Aktion.
curl http://$GATEWAY_HOST_EXT/productpage
#Traffic vom User zum externen Gateway-Endpoint
kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST_INT/productpage"
#Traffic vom Pod zum internen Gateway-Endpoint
kubectl exec deploy/sleep -- curl -s http://productpage:9080/
#Traffic vom Pod direkt zum Service
kubectl exec deploy/notsleep -- curl -s http://productpage:9080/
#Traffic vom Pod direkt zum Service
Werfen Sie erneut einen Blick auf den Kiali-Graphen. Er sollte nun mit Daten gefüllt sein und mTLS-gesicherte Kommunikation sowie weitere nützliche Telemetriedaten zeigen.

L7-Autorisierungsrichtlinien anwenden
Da das sichere Overlay nun steht, lassen sich L4-Autorisierungsrichtlinien ohne Weiteres anwenden – genauso wie beim klassischen Istio.
Allerdings bietet dieses sichere Overlay keine L7-Filterung. Dafür müssen wir einen Envoy-basierten Waypoint-Proxy für den productpage-Service ausrollen.
Der Proxy wird auf den Service Account angewendet – im Fall des productpage-Service ist das der Service Account bookinfo-productpage.
Rollen Sie einen Waypoint-Proxy für den productpage-Service aus:
istioctl x waypoint apply --service-account bookinfo-productpage
Damit wird ein Waypoint-Proxy für jeden Service bereitgestellt, der den Service Account bookinfo-productpage verwendet.


Sämtlicher Traffic an den productpage-Service läuft nun zwingend über den L7-Proxy, der je nach Auslastung automatisch skaliert.
Erstellen wir nun eine L7-AuthorizationPolicy, die den Service Accounts sleep und Gateway explizit erlaubt, den productpage-Service per GET abzurufen, andere Operationen aber unterbindet.
export GATEWAY_SERVICE_ACCOUNT=ns/istio-system/sa/istio-ingressgateway-service-account
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: productpage-viewer
namespace: default
spec:
targetRef:
kind: Gateway
group: gateway.networking.k8s.io
name: bookinfo-productpage
action: ALLOW
rules:
- from:
- source:
principals:
- cluster.local/ns/default/sa/sleep
- cluster.local/$GATEWAY_SERVICE_ACCOUNT
to:
- operation:
methods: ["GET"]
EOF
Testen Sie die Richtlinie in Aktion:
# Sollte mit einem RBAC-Fehler fehlschlagen, da es keine GET-Operation ist
kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" -X DELETE
# Ausgabe sollte 'RBAC: access denied' sein
# Sollte mit einem RBAC-Fehler fehlschlagen, da diese Identität nicht zugelassen ist
kubectl exec deploy/notsleep -- curl -s http://productpage:9080/
# Ausgabe sollte 'RBAC: access denied' sein
# Sollte weiterhin funktionieren
kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
# Ausgabe sollte '<title>Simple Bookstore App</title>' sein
Aufräumen
Führen Sie die folgenden Befehle aus, um Istio und seine Komponenten zu deinstallieren:
istioctl x waypoint delete --all
istioctl uninstall -y --purge
kubectl delete namespace istio-system
GKE-Cluster löschen:
gcloud container clusters delete $CLUSTER_NAME --zone $ZONE
Bemerkenswert, wie konsequent die L4- und L7-Funktionalitäten im Sinne von Flexibilität und Effizienz modularisiert wurden.
Mich interessiert besonders, wie sich die Vorteile bei großem Maßstab auswirken – Ambient Mesh in einer echten Produktivumgebung im Einsatz zu sehen, fände ich spannend.
Ich hoffe, dieser Artikel war hilfreich und aufschlussreich. Teilen Sie Ihre Gedanken und Ihr Feedback gerne in den Kommentaren.