Welches Problem löst ein Service Mesh?
Sobald eine Anwendung aus vielen Services besteht, braucht jeder Service dieselben Grundfunktionen. Ohne Mesh baut jedes Team sie selbst ein – in jeder Programmiersprache, jeweils etwas anders.
Was jeder Service braucht
- Verschlüsselung zwischen den Services (mTLS)
- Identität: wer ruft mich eigentlich auf?
- Zugriffsregeln: wer darf wen aufrufen, mit welcher Methode?
- Robustheit: Timeouts, Retries, Circuit Breaking
- Traffic-Steuerung: Canary-Releases, A/B-Tests, Routing nach Header
- Sichtbarkeit: Metriken, Access-Logs, Tracing für jeden Aufruf
Das Bild: eine Firma mit Assistenz
Jeder Mitarbeiter (Service) hat eine persönliche Assistenz (Proxy). Der Mitarbeiter sagt nur: „Verbinde mich mit der Buchhaltung.“ Die Assistenz erledigt den Rest:
- Sie ruft verschlüsselt an.
- Sie zeigt einen Dienstausweis vor.
- Sie versucht es bei „besetzt“ erneut.
- Sie legt nach 5 Sekunden auf, wenn niemand antwortet.
- Sie protokolliert jeden Anruf.
- Sie stellt eingehende Anrufe nur durch, wenn der Anrufer auf der Liste steht.
Die Zentrale (istiod) verteilt an alle Assistenzen das Telefonbuch, die Regeln und die Dienstausweise. Sie telefoniert selbst nie mit.
Architektur: Control Plane und Data Plane
Zwei Ebenen, streng getrennt: istiod verteilt Konfiguration und Zertifikate, die Proxies führen den Datenverkehr. Konfiguration und Daten laufen nie über denselben Weg.
Der Aufbau im Sidecar-Modus
Control Plane: istiod
Ein einzelnes Deployment im Namespace istio-system mit drei Aufgaben:
- Konfiguration übersetzenLiest Kubernetes-Objekte (Services, Endpoints) und Istio-Ressourcen und übersetzt sie in Envoy-Konfiguration.
- Konfiguration verteilenSchickt sie per xDS (gRPC-Stream) an alle Proxies. Änderungen kommen in Sekunden an, ohne Neustart.
- Zertifikate ausstellenArbeitet als Zertifizierungsstelle: Jeder Workload bekommt ein kurzlebiges X.509-Zertifikat mit seiner Identität und erneuert es automatisch.
Data Plane: Envoy (oder ztunnel)
Der Envoy-Proxy ist ein L7-Proxy und sitzt im Sidecar-Modus als zusätzlicher Container (istio-proxy) in jedem Pod. Ein- und ausgehender Traffic wird per iptables- bzw. nftables-Regeln durch ihn umgeleitet. Die Regeln setzt entweder ein Init-Container (istio-init) oder das Istio-CNI-Plugin.
NET_ADMIN-Rechte bekommen.Identität: SPIFFE
Jeder Workload bekommt eine Identität, die an seinen ServiceAccount gebunden ist:
spiffe://cluster.local/ns/bookinfo/sa/bookinfo-productpage
Diese Identität steckt im Zertifikat und wird bei jedem mTLS-Handshake geprüft. Autorisierungsregeln beziehen sich darauf, nicht auf IP-Adressen – Pod-IPs ändern sich ständig, die Identität bleibt.
Sidecar-Modus gegen Ambient-Modus
Istio hat zwei Betriebsarten für die Data Plane. Der Unterschied entscheidet über Ressourcenverbrauch, Einführungsaufwand und darüber, ob Pods neu starten müssen.
Beide Modi nebeneinander
Sidecar-Modus (klassisch)
Jeder Pod bekommt einen eigenen Envoy. Alle Funktionen sind immer verfügbar, auf Kosten von CPU und RAM pro Pod. Zum Einschalten müssen die Pods neu starten, damit der Sidecar injiziert wird.
Ambient-Modus (ohne Sidecar)
ztunnel läuft als DaemonSet einmal pro Node, in Rust geschrieben, und arbeitet nur auf L4: mTLS, Identität, einfache Zugriffsregeln, Metriken pro Verbindung. Zwischen den ztunnels läuft der Traffic über das Tunnelprotokoll HBONE auf Port 15008.
Ein Waypoint ist ein Envoy-Proxy als eigenes Deployment, typischerweise einer pro Namespace. Er wird nur eingerichtet, wenn L7-Funktionen gebraucht werden.
| Sidecar | Ambient | |
|---|---|---|
| Proxy | Envoy in jedem Pod | ztunnel pro Node + optional Waypoint |
| Einschalten | Namespace labeln + Pods neu starten | Namespace labeln, kein Neustart |
| Ressourcen | pro Pod (Default-Request 100m CPU / 128Mi) | pro Node + pro Waypoint |
| L7-Funktionen | immer | nur mit Waypoint |
| Reife | seit Jahren Standard | in Istio GA, in OpenShift Service Mesh seit 3.2 GA |
| Typischer Einstieg | volle L7-Kontrolle für alle Services | „erst mal mTLS überall“, L7 gezielt nachrüsten |
Die wichtigsten Ressourcen
Istio hat viele CRDs. Für den Einstieg reichen diese – sortiert nach der Frage, die jede beantwortet.
Traffic-Steuerung: die Kette
Client
│
▼
Gateway Eingang: welche Hosts und Ports?
│
▼
VirtualService WOHIN: Regeln nach Pfad, Header, Gewicht
oder HTTPRoute
│
▼
DestinationRule WIE: Subsets, Loadbalancing, Circuit Breaker
│
├──▸ reviews v1
└──▸ reviews v3
| Ressource | Frage, die sie beantwortet | Bild |
|---|---|---|
| Gateway | Welcher Traffic darf von außen herein (Host, Port, TLS)? | Empfang am Firmeneingang |
| VirtualService | Wohin geht ein Request? (Pfad, Header, Gewichte, Timeouts, Retries) | Navi |
| DestinationRule | Wie wird das Ziel angesprochen? (Subsets, LB-Algorithmus, Verbindungslimits, Outlier Detection) | Hausordnung am Ziel |
| ServiceEntry | Welche externen Ziele kennt das Mesh? | Telefonbuch für externe Nummern |
| Sidecar | Welche Ziele muss ein Proxy überhaupt kennen? | Reduziert die Konfiguration pro Proxy |
Gateway API: der neue Standard
Istio unterstützt neben den eigenen APIs die Kubernetes Gateway API und empfiehlt sie für neue Setups. Im Ambient-Modus ist sie der bevorzugte Weg.
| Istio-API | Gateway-API-Entsprechung |
|---|---|
Gateway (networking.istio.io) | Gateway (gateway.networking.k8s.io) – Istio startet dafür automatisch ein Gateway-Deployment |
VirtualService | HTTPRoute, GRPCRoute, TLSRoute, TCPRoute |
Subsets in DestinationRule | eigene Services pro Version als backendRefs |
DestinationRule (Traffic-Policy) | bleibt als Istio-Ressource bestehen |
In bestehenden Clustern trifft man noch überwiegend VirtualService und DestinationRule. Die Beispiele unten zeigen beide Varianten.
Sicherheit
| Ressource | Frage | Bild |
|---|---|---|
| PeerAuthentication | Muss sich der Aufrufer per mTLS ausweisen? | Dienstausweis-Pflicht |
| RequestAuthentication | Ist das mitgeschickte JWT gültig? | Besucherticket prüfen |
| AuthorizationPolicy | Darf dieser Aufrufer das tun? | Gästeliste pro Raum |
Installation
Im Lab genügt istioctl. Unter OpenShift läuft alles über den Sail Operator – istioctl install und Helm werden dort nicht unterstützt.
Testcluster mit istioctl (kind, k3s, minikube, RKE2)
# istioctl und Beispieldateien herunterladen
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.31.1
export PATH=$PWD/bin:$PATH
# Cluster prüfen
istioctl x precheck
# Gateway-API-CRDs installieren, falls nicht vorhanden
kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=<version>" | kubectl apply -f -
# Istio installieren: Demo-Profil ohne vorinstallierte Gateways
istioctl install -f samples/bookinfo/demo-profile-no-gateways.yaml -y
kubectl get pods -n istio-system
default oder minimal verwenden und gezielt anpassen.Namespace in das Mesh aufnehmen (Sidecar-Modus)
kubectl create namespace bookinfo
kubectl label namespace bookinfo istio-injection=enabled
Das Label wirkt nur auf neu erstellte Pods. Ein Mutating Webhook von istiod fügt den istio-proxy-Container beim Erstellen hinzu. Bestehende Pods brauchen einen Neustart:
kubectl rollout restart deployment -n bookinfo
OpenShift Service Mesh 3 über den Sail Operator
OSSM 3 ist Istio, verwaltet durch den Sail Operator. Die Installation läuft ausschließlich über den Operator; einzelne istioctl-Befehle zur Analyse sind unterstützt.
1. Operator „Red Hat OpenShift Service Mesh 3“ aus dem OperatorHub installieren.
2. Namespaces anlegen und die Control Plane erstellen:
oc create namespace istio-system
oc create namespace istio-cni
oc label namespace istio-system istio-discovery=enabled
apiVersion: sailoperator.io/v1
kind: Istio
metadata:
name: default
spec:
namespace: istio-system
updateStrategy:
type: InPlace
values:
meshConfig:
discoverySelectors:
- matchLabels:
istio-discovery: enabled
---
apiVersion: sailoperator.io/v1
kind: IstioCNI
metadata:
name: default
spec:
namespace: istio-cni
3. Anwendungs-Namespaces aufnehmen:
oc create namespace bookinfo
oc label namespace bookinfo istio-discovery=enabled istio-injection=enabled
Was unter OpenShift anders ist
- discoverySelectors: istiod beobachtet nur Namespaces mit passendem Label. Das begrenzt Last und Speicher in großen Clustern –
istio-systemmuss selbst das Label tragen. - Ohne
spec.versioninstalliert der Operator die neueste unterstützte Istio-Version. Für reproduzierbare Setups die Version fest setzen. - Gateways werden nicht mitinstalliert – entweder über die Gateway API oder per Gateway-Injection als eigenes Deployment. Nach außen führt eine OpenShift-Route oder ein LoadBalancer-Service darauf.
- Kiali, Metriken und Tracing sind separat: Kiali über den Kiali-Operator, Metriken über User Workload Monitoring, Tracing über Tempo und OpenTelemetry.
- Upgrades mit
updateStrategy: RevisionBasedlaufen als Canary: neue Control Plane parallel, Namespaces nach und nach umziehen. - Ambient-Modus: Istio mit
profile: ambientplus eineZTunnel-Ressource. Seit OSSM 3.2 GA.
Erste Schritte: Bookinfo
Die Beispielanwendung von Istio: productpage (Web-UI) ruft details und reviews auf, reviews ruft ratings auf. reviews gibt es in drei Versionen – v1 ohne Sterne, v2 mit schwarzen, v3 mit roten.
Die Services und ihre Aufrufe
Anwendung deployen und Proxy-Status prüfen
kubectl apply -n bookinfo -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl apply -n bookinfo -f samples/bookinfo/platform/kube/bookinfo-versions.yaml
kubectl get pods -n bookinfo
Jeder Pod zeigt zwei Container: die App und istio-proxy. Ob alle Proxies ihre Konfiguration bekommen haben:
istioctl proxy-status
SYNCED in allen Spalten heißt: Der Proxy hat den aktuellen Stand von istiod.
Eingang von außen
kubectl apply -n bookinfo -f samples/bookinfo/gateway-api/bookinfo-gateway.yaml
kubectl wait -n bookinfo --for=condition=programmed gtw bookinfo-gateway
Istio erzeugt automatisch Deployment und Service bookinfo-gateway-istio. Ohne LoadBalancer im Lab:
kubectl port-forward -n bookinfo svc/bookinfo-gateway-istio 8080:80
# Browser: http://localhost:8080/productpage
Beim mehrfachen Neuladen wechseln die Sterne zwischen keinen, schwarzen und roten.
Konfiguration prüfen
istioctl analyze -n bookinfo
analyze findet typische Fehler: VirtualService zeigt auf ein nicht existierendes Subset, fehlendes Injection-Label, Konflikte zwischen Regeln.
istioctl analyze nach jeder Änderung – das ist die billigste Fehlersuche, die es gibt.Praxisbeispiele
Zehn Fälle zum Nachbauen, alle im Sidecar-Modus mit Bookinfo. Jeder Block ist für sich anwendbar.
6.1 · mTLS erzwingen
Istio startet im Modus PERMISSIVE: Proxies nehmen mTLS und Klartext an. Das erlaubt eine schrittweise Migration. Zwischen zwei Proxies wird trotzdem automatisch mTLS verwendet.
| Modus | Verhalten |
|---|---|
PERMISSIVE | mTLS und Klartext (Default) |
STRICT | nur mTLS, Klartext wird abgelehnt |
DISABLE | kein mTLS |
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
namespace: bookinfo
spec:
mtls:
mode: STRICT
Mesh-weit: dieselbe Ressource im Namespace istio-system anlegen. Test – ein Pod ohne Sidecar erreicht die Services nicht mehr:
kubectl create namespace legacy # ohne Injection-Label
kubectl apply -n legacy -f samples/curl/curl.yaml
kubectl exec -n legacy deploy/curl -- curl -s -o /dev/null -w "%{http_code}\n" \
http://productpage.bookinfo:9080/productpage
# Ergebnis: 000 bzw. "connection reset" statt 200
6.2 · Alle Nutzer auf eine Version festlegen
Erst die Versionen als Subsets definieren (Wie), dann den Traffic lenken (Wohin):
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: reviews
namespace: bookinfo
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews
namespace: bookinfo
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
Die Seite zeigt jetzt dauerhaft keine Sterne. Die Subsets greifen über Pod-Labels – version: v1 muss also als Label auf den Pods existieren.
6.3 · Canary-Release: 90/10
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews
namespace: bookinfo
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 90
- destination:
host: reviews
subset: v3
weight: 10
Dasselbe mit der Gateway API – statt Subsets ein eigener Service pro Version, den bookinfo-versions.yaml bereits angelegt hat:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: reviews
namespace: bookinfo
spec:
parentRefs:
- group: ""
kind: Service
name: reviews
port: 9080
rules:
- backendRefs:
- name: reviews-v1
port: 9080
weight: 90
- name: reviews-v3
port: 9080
weight: 10
Hochdrehen: 90/10 → 50/50 → 0/100, jeweils Fehlerraten und Latenz beobachten. Nicht gleichzeitig VirtualService und HTTPRoute für denselben Service verwenden.
6.4 · Routing nach Header: Testnutzer sehen die neue Version
Nur ein bestimmter Nutzer sieht v2, alle anderen bleiben auf v1. Bookinfo setzt nach dem Login den Header end-user.
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews
namespace: bookinfo
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
match gehört deshalb ans Ende.Damit das funktioniert, muss die Anwendung den Header an ihre eigenen ausgehenden Aufrufe weiterreichen. Istio kann nur routen, was im Request steht. Dasselbe gilt für Tracing-Header: Ohne Weitergabe in der App zerfallen Traces in Einzelteile.
6.5 · Timeouts und Retries
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ratings
namespace: bookinfo
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
timeout: 3s
retries:
attempts: 2
perTryTimeout: 1s
retryOn: 5xx,connect-failure,reset
timeoutist die Gesamtzeit inklusive aller Retries.- Retries nur für idempotente Operationen. Ein wiederholtes
POST /bestellungkann zwei Bestellungen erzeugen. - Istio führt standardmäßig bereits Retries durch. Bei Retries in der App und im Mesh multiplizieren sich die Versuche.
6.6 · Fault Injection: Fehler absichtlich einbauen
Wie verhält sich die Anwendung, wenn ein abhängiger Service langsam ist oder Fehler liefert? Testbar ohne Codeänderung:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ratings
namespace: bookinfo
spec:
hosts:
- ratings
http:
- fault:
delay:
percentage:
value: 50
fixedDelay: 5s
abort:
percentage:
value: 10
httpStatus: 503
route:
- destination:
host: ratings
50 % der Requests werden um 5 Sekunden verzögert, 10 % bekommen ein 503. Fragen, die der Test beantwortet: Zeigt productpage eine saubere Fehlermeldung oder hängt die Seite? Passen die Timeouts der aufrufenden Services zueinander?
6.7 · Circuit Breaking und Outlier Detection
- connectionPool begrenzt, wie viele Verbindungen und wartende Requests ein Ziel bekommt. Ist es voll, wird sofort abgelehnt, statt einen überlasteten Service weiter zu fluten.
- outlierDetection wirft einzelne Pods temporär aus dem Loadbalancing, wenn sie wiederholt Fehler liefern.
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: reviews
namespace: bookinfo
spec:
host: reviews
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 50
maxRequestsPerConnection: 10
outlierDetection:
consecutive5xxErrors: 5
interval: 10s
baseEjectionTime: 30s
maxEjectionPercent: 50
subsets:
- name: v1
labels:
version: v1
- name: v3
labels:
version: v3
maxEjectionPercent verhindert, dass alle Pods gleichzeitig ausgeschlossen werden. Abgelehnte Requests erscheinen im Access-Log mit dem Flag UO. Zum Ausprobieren eignet sich fortio aus samples/httpbin/sample-client/fortio-deploy.yaml.
6.8 · Zugriff regeln mit AuthorizationPolicy
Die Auswertung läuft in fester Reihenfolge:
Sauberes Vorgehen: erst alles verbieten, dann gezielt erlauben.
# 1. Alles im Namespace verbieten
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
namespace: bookinfo
spec: {}
---
# 2. Das Gateway darf productpage aufrufen
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: productpage-from-gateway
namespace: bookinfo
spec:
selector:
matchLabels:
app: productpage
action: ALLOW
rules:
- from:
- source:
principals:
- cluster.local/ns/bookinfo/sa/bookinfo-gateway-istio
to:
- operation:
methods: ["GET"]
---
# 3. productpage darf reviews lesen, sonst niemand
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: reviews-from-productpage
namespace: bookinfo
spec:
selector:
matchLabels:
app: reviews
action: ALLOW
rules:
- from:
- source:
principals:
- cluster.local/ns/bookinfo/sa/bookinfo-productpage
to:
- operation:
methods: ["GET"]
Dasselbe Muster für details (von productpage) und ratings (von reviews) ergänzen. Welche Identität ein Aufrufer hat, zeigt istioctl x describe pod <pod> -n bookinfo. Der Name des Gateway-ServiceAccounts hängt vom Gateway-Namen ab: kubectl get sa -n bookinfo. Abgelehnte Requests liefern HTTP 403 mit RBAC: access denied.
6.9 · Ausgehenden Traffic kontrollieren
Standardmäßig dürfen Pods im Mesh jedes externe Ziel erreichen (ALLOW_ANY). Strenger ist REGISTRY_ONLY: Nur bekannte Ziele sind erreichbar.
istioctl install ... --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
Unter OSSM 3 kommt die Einstellung in spec.values.meshConfig.outboundTrafficPolicy.mode der Istio-Ressource. Danach jedes erlaubte Ziel per ServiceEntry freigeben:
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: github-api
namespace: bookinfo
spec:
hosts:
- api.github.com
ports:
- number: 443
name: tls
protocol: TLS
resolution: DNS
location: MESH_EXTERNAL
6.10 · Sichtbarkeit: Kiali, Metriken, Access-Logs
kubectl apply -f samples/addons
kubectl rollout status deployment/kiali -n istio-system
istioctl dashboard kiali
Kiali zeigt den Service-Graphen live: wer mit wem spricht, Fehlerraten, Latenzen, ob mTLS aktiv ist (Schloss-Symbol) und Validierungsfehler in der Istio-Konfiguration. Für Einsteiger das wichtigste Werkzeug, um zu sehen, was die Regeln bewirken.
samples/addons sind Lab-Werkzeuge. Unter OpenShift stattdessen den Kiali-Operator und User Workload Monitoring verwenden.Access-Logs für das ganze Mesh einschalten:
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
name: mesh-default
namespace: istio-system
spec:
accessLogging:
- providers:
- name: envoy
kubectl logs -n bookinfo deploy/productpage-v1 -c istio-proxy --tail=20
Dasselbe im Ambient-Modus
Was sich ändert, wenn statt Sidecars ein ztunnel pro Node arbeitet – und wo die eine Falle liegt, die fast jeder trifft.
Installation und Aufnahme
istioctl install --set profile=ambient --skip-confirmation
kubectl label namespace bookinfo istio.io/dataplane-mode=ambient
Kein Pod-Neustart nötig. Die Pods bleiben bei einem Container. Ab sofort läuft ihr Traffic über den ztunnel des Nodes und ist per mTLS verschlüsselt.
istioctl ztunnel-config workloads
# Spalte PROTOCOL zeigt HBONE für Workloads im Mesh
Sofort verfügbar (L4)
- mTLS zwischen allen Workloads
- AuthorizationPolicy mit
principalsund Ports – aber ohne HTTP-Methoden oder Pfade - Metriken auf Verbindungsebene
Für L7 einen Waypoint
istioctl waypoint apply -n bookinfo \
--enroll-namespace --wait
Danach funktionieren die L7-Beispiele. Routing läuft bevorzugt über HTTPRoute.
L7-Policies hängen am Waypoint
Statt über selector werden sie über targetRefs zugeordnet:
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: reviews-get-only
namespace: bookinfo
spec:
targetRefs:
- kind: Service
group: ""
name: reviews
action: ALLOW
rules:
- from:
- source:
principals:
- cluster.local/ns/bookinfo/sa/bookinfo-productpage
to:
- operation:
methods: ["GET"]
selector statt targetRefs kann der ztunnel nicht auswerten, weil er nur L4 sieht. Die Regel greift dann nicht wie erwartet – istioctl analyze warnt davor.Was zu beachten ist
Sechs Bereiche, in denen ein Mesh Dinge kaputtmacht, die vorher liefen – meist ohne aussagekräftige Fehlermeldung.
Ports korrekt benennen
Istio muss wissen, welches Protokoll auf einem Port läuft. Es erkennt HTTP oft automatisch, explizit ist aber besser: Port-Name mit Präfix (http-, grpc-, tcp-, tls-) oder das Feld appProtocol im Service.
ports:
- name: http-web
port: 8080
- name: tcp-mysql
port: 3306
tcp deklarieren.Startreihenfolge und Jobs
- Startet die App schneller als der Proxy, schlagen ihre ersten ausgehenden Verbindungen fehl. Abhilfe:
holdApplicationUntilProxyStarts: true. - Klassische Sidecars beenden sich nicht, wenn der Hauptcontainer fertig ist – dadurch bleiben Jobs und CronJobs hängen. Neuere Istio-Versionen können den Proxy als nativen Kubernetes-Sidecar starten (Init-Container mit
restartPolicy: Always), was beide Probleme löst. Stand in der eigenen Version prüfen. - Im Ambient-Modus gibt es beide Probleme nicht.
Health-Probes und STRICT mTLS
Das kubelet hat kein Mesh-Zertifikat. Damit HTTP-Probes bei STRICT mTLS nicht scheitern, schreibt Istio sie standardmäßig um: Sie gehen an den Istio-Agenten im Pod (Port 15020), der sie lokal an die App weiterreicht. Das passiert automatisch – wer es abschaltet, muss die Probes selbst anpassen.
NetworkPolicies zusammen mit dem Mesh
- Proxies müssen istiod erreichen: Port 15012 (xDS) im Namespace
istio-system. - Der API-Server muss den Webhook von istiod erreichen: Port 15017.
- Im Ambient-Modus läuft Traffic zwischen Pods über Port 15008 (HBONE). NetworkPolicies müssen diesen Port erlauben – die eigentlichen App-Ports sind im Netz nicht mehr sichtbar.
Ressourcen und Skalierung
- Jeder Sidecar kostet standardmäßig mindestens 100m CPU und 128Mi RAM als Request. Bei 500 Pods kommt einiges zusammen. Pro Workload anpassbar über
sidecar.istio.io/proxyCPUundsidecar.istio.io/proxyMemory. - In großen Clustern kennt jeder Proxy standardmäßig alle Services. Die
Sidecar-Ressource unddiscoverySelectorsreduzieren das auf das Nötige und sparen viel Speicher.
Upgrades
- Control Plane und Proxies dürfen sich um höchstens ein bis zwei Minor-Versionen unterscheiden (Version-Skew in der Istio-Doku).
- Nach einem Control-Plane-Upgrade im Sidecar-Modus behalten Pods die alte Proxy-Version, bis sie neu starten. Ein Upgrade ist erst abgeschlossen, wenn alle Workloads neu gestartet wurden.
- Für Produktion Revisions nutzen: neue Control Plane parallel installieren, Namespaces per Label
istio.io/rev=<revision>einzeln umziehen, alte Control Plane zum Schluss entfernen. - Im Ambient-Modus betrifft ein ztunnel-Upgrade alle Pods auf dem Node. Laufende Verbindungen können abreißen – Nodes vorher drainen.
Istio veröffentlicht schnell
Etwa alle drei Monate erscheint eine neue Minor-Version, unterstützt werden jeweils nur die letzten zwei bis drei. Ein Cluster, der ein Jahr nicht angefasst wird, ist aus dem Support-Fenster gefallen.
Debugging und Spickzettel
Eine feste Reihenfolge und eine Handvoll Befehle decken die meisten Fälle ab. Das Response-Flag im Access-Log ist oft der schnellste Weg zur Ursache.
Vorgehen
istioctl analyze -n <ns>Warnungen? Dann zuerst die Konfiguration korrigieren – das erledigt die meisten Fälle.istioctl proxy-statusAlleSYNCED? Wenn nicht: istiod-Logs prüfen, der Proxy erreicht istiod nicht.- Access-Log des Proxys lesenStatus-Code plus Response-Flag – siehe Tabelle unten.
istioctl proxy-config …Kommt die Regel überhaupt im Proxy an?
Wichtige istioctl-Befehle
| Befehl | Zeigt |
|---|---|
istioctl analyze -n <ns> | Konfigurationsfehler |
istioctl proxy-status | ob jeder Proxy den aktuellen Stand hat |
istioctl x describe pod <pod> -n <ns> | welche Regeln für einen Pod gelten, mTLS-Status |
istioctl proxy-config routes deploy/<name> -n <ns> | Routen, wie Envoy sie sieht |
istioctl proxy-config cluster deploy/<name> -n <ns> | bekannte Ziele (Cluster) |
istioctl proxy-config endpoint deploy/<name> -n <ns> | konkrete Pod-IPs pro Ziel inklusive Health |
istioctl proxy-config secret deploy/<name> -n <ns> | Zertifikate des Proxys |
istioctl ztunnel-config workloads | Ambient: Workloads und Protokoll |
Response-Flags im Access-Log
| Flag | Bedeutung | Typische Ursache |
|---|---|---|
NR | No Route | keine Route passt: VirtualService falsch, Host stimmt nicht |
UH | No Healthy Upstream | keine gesunden Pods: alle ausgeworfen oder keine Endpoints |
UF | Upstream Connection Failure | mTLS-Konflikt, App lauscht nicht |
UO | Upstream Overflow | Circuit Breaker hat abgelehnt |
URX | Retry Limit Exceeded | alle Retries fehlgeschlagen |
UT | Upstream Timeout | Timeout aus dem VirtualService erreicht |
DC | Downstream Connection Termination | Client hat die Verbindung abgebrochen |
UF direkt nach dem Umstellen auf STRICT deutet fast immer auf einen Client ohne Sidecar hin – oder auf eine DestinationRule, die TLS für dieses Ziel abschaltet.Labels und Ports zum Nachschlagen
| Label | Wirkung |
|---|---|
istio-injection=enabled | Sidecar-Injection für den Namespace (nach Pod-Neustart) |
istio.io/rev=<revision> | Sidecar einer bestimmten Control-Plane-Revision |
istio.io/dataplane-mode=ambient | Namespace oder Pod in den Ambient-Mesh aufnehmen |
istio.io/use-waypoint=<name> | Service oder Namespace nutzt diesen Waypoint |
| Port | Zweck |
|---|---|
| 15001 | Envoy: ausgehender Traffic (umgeleitet) |
| 15006 | Envoy: eingehender Traffic (umgeleitet) |
| 15000 | Envoy Admin (nur localhost) |
| 15008 | HBONE-Tunnel (Ambient, mTLS) |
| 15012 | istiod: xDS und Zertifikate |
| 15017 | istiod: Webhook |
| 15020 | Istio-Agent: Metriken, Probe-Umleitung |
| 15021 | Health-Check des Proxys |
| 15090 | Envoy-Metriken für Prometheus |
Die Eselsbrücken auf einen Blick
- VirtualService = Wohin, DestinationRule = Wie.
- PeerAuthentication = Ausweispflicht, AuthorizationPolicy = Gästeliste.
- Der ServiceAccount ist der Ausweis.
- Die erste ALLOW-Policy macht aus „alles erlaubt“ ein „alles verboten außer“.
istioctl analyzenach jeder Änderung.
Mindestablauf für ein neues Projekt
- Namespace labelnInjection oder Ambient.
- Prüfen
istioctl analyzeundistioctl proxy-status. - PeerAuthentication auf STRICTsobald alle Clients im Mesh sind.
allow-nothingplus gezielte ALLOW-Policies- Timeouts setzenRetries nur für idempotente Aufrufe.
- Kiali und Access-Logs zur Kontrolle