Alle Rezepte
Istio 1.31 · OpenShift Service Mesh 3.x · Service Mesh

Istio für Einsteiger:
Konzepte, Einrichtung, Praxis

Ein Service Mesh zieht Verschlüsselung, Identität, Zugriffsregeln und Traffic-Steuerung aus der Anwendung heraus in die Infrastruktur. Zehn Abschnitte von der Architektur über Installation auf Kubernetes und OpenShift bis zu zehn Praxisbeispielen zum Nachbauen.

0Warum ein MeshDas Problem dahinter 1Architekturistiod, Envoy, SPIFFE 2Sidecar vs. AmbientZwei Betriebsarten 3RessourcenWohin, Wie, Wer darf 4InstallationLab und OpenShift 5BookinfoErste Schritte 6PraxisbeispieleZehn Fälle 7Ambient-ModusWas sich ändert 8StolperfallenPorts, Jobs, Upgrades 9Debuggingistioctl, Response-Flags
0

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.

Die Assistenz ist der Proxy (Data Plane), die Zentrale ist istiod (Control Plane). Dieses Bild trägt durch den ganzen Artikel.
Voraussetzungen: Kubernetes-Grundlagen (Pods, Services, Deployments, Labels). Hilfreich ist ein Grundverständnis der Netzwerk-Layer, vor allem der Unterschied zwischen L4 (Verbindung, Port) und L7 (HTTP-Inhalt).
1

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

istiod Control Plane: Regeln, Zertifikate xDS Pod A · productpage App Envoy Sidecar Pod B · reviews Envoy Sidecar App mTLS Klartext an reviews:9080 – wird zum Envoy umgeleitet Envoy prüft Identität + Policy, reicht Klartext an die App Durchgezogen: Datenverkehr (Data Plane) · Gestrichelt: Konfiguration (Control Plane) Die App merkt nichts – sie spricht weiter Klartext mit ihrem Ziel.

Control Plane: istiod

Ein einzelnes Deployment im Namespace istio-system mit drei Aufgaben:

  1. Konfiguration übersetzenLiest Kubernetes-Objekte (Services, Endpoints) und Istio-Ressourcen und übersetzt sie in Envoy-Konfiguration.
  2. Konfiguration verteilenSchickt sie per xDS (gRPC-Stream) an alle Proxies. Änderungen kommen in Sekunden an, ohne Neustart.
  3. 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.

Unter OpenShift ist das CNI-Plugin Pflicht, weil Pods dort keine 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.

Der ServiceAccount ist der Ausweis. Wer allen Pods denselben ServiceAccount gibt, kann sie nicht mehr unterscheiden.
2

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 Node App Envoy L4+L7 App Envoy L4+L7 App Envoy L4+L7 Ein Envoy pro Pod, L7 immer aktiv Einschalten = Pods neu starten Ambient-Modus Node App App App ztunnel L4 · mTLS Waypoint (optional) L7 · pro Namespace Pods bleiben unverändert Violett = L4 (Verbindung) · Orange = L7 (HTTP-Inhalt)

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.

Statt einer Assistenz pro Mitarbeiter gibt es eine Telefonzentrale pro Etage (ztunnel) – sie verbindet verschlüsselt und prüft Ausweise, hört aber nicht zu. Wer mehr braucht, bekommt ein Sekretariat pro Abteilung (Waypoint), das den Inhalt versteht.
SidecarAmbient
ProxyEnvoy in jedem Podztunnel pro Node + optional Waypoint
EinschaltenNamespace labeln + Pods neu startenNamespace labeln, kein Neustart
Ressourcenpro Pod (Default-Request 100m CPU / 128Mi)pro Node + pro Waypoint
L7-Funktionenimmernur mit Waypoint
Reifeseit Jahren Standardin Istio GA, in OpenShift Service Mesh seit 3.2 GA
Typischer Einstiegvolle L7-Kontrolle für alle Services„erst mal mTLS überall“, L7 gezielt nachrüsten
Empfehlung: Für Neuanfänge ist Ambient attraktiv – mTLS ohne Pod-Neustart und mit wenig Overhead. Zum Lernen der Konzepte ist der Sidecar-Modus besser geeignet: Alle Beispiele im Netz funktionieren, und jeder Pod zeigt direkt, was passiert. Beide Modi nicht innerhalb eng gekoppelter Anwendungen mischen. Die Beispiele hier nutzen den Sidecar-Modus; Abschnitt 7 zeigt die Unterschiede.
3

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
RessourceFrage, die sie beantwortetBild
GatewayWelcher Traffic darf von außen herein (Host, Port, TLS)?Empfang am Firmeneingang
VirtualServiceWohin geht ein Request? (Pfad, Header, Gewichte, Timeouts, Retries)Navi
DestinationRuleWie wird das Ziel angesprochen? (Subsets, LB-Algorithmus, Verbindungslimits, Outlier Detection)Hausordnung am Ziel
ServiceEntryWelche externen Ziele kennt das Mesh?Telefonbuch für externe Nummern
SidecarWelche Ziele muss ein Proxy überhaupt kennen?Reduziert die Konfiguration pro Proxy
VirtualService = Wohin. DestinationRule = Wie. Die DestinationRule definiert die Versionen (Subsets), der VirtualService verteilt darauf.
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-APIGateway-API-Entsprechung
Gateway (networking.istio.io)Gateway (gateway.networking.k8s.io) – Istio startet dafür automatisch ein Gateway-Deployment
VirtualServiceHTTPRoute, GRPCRoute, TLSRoute, TCPRoute
Subsets in DestinationRuleeigene 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

RessourceFrageBild
PeerAuthenticationMuss sich der Aufrufer per mTLS ausweisen?Dienstausweis-Pflicht
RequestAuthenticationIst das mitgeschickte JWT gültig?Besucherticket prüfen
AuthorizationPolicyDarf dieser Aufrufer das tun?Gästeliste pro Raum
RequestAuthentication allein blockiert nichts. Sie lehnt nur ungültige Tokens ab. Requests ganz ohne Token kommen durch, solange keine AuthorizationPolicy ein Token verlangt.
Beobachtung: Die Ressource Telemetry stellt Access-Logs, Metriken und Tracing pro Mesh, Namespace oder Workload ein.
4

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
Nur fürs Lernen: Das Demo-Profil hat unter anderem 100 % Trace-Sampling. Für Produktion 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-system muss selbst das Label tragen.
  • Ohne spec.version installiert 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: RevisionBased laufen als Canary: neue Control Plane parallel, Namespaces nach und nach umziehen.
  • Ambient-Modus: Istio mit profile: ambient plus eine ZTunnel-Ressource. Seit OSSM 3.2 GA.
5

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

Browser Gateway productpage details reviews v1 keine Sterne reviews v2 schwarze Sterne reviews v3 rote Sterne ratings Ohne Regeln verteilt der Kubernetes-Service gleichmäßig auf alle drei reviews-Versionen.
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.
6

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.

ModusVerhalten
PERMISSIVEmTLS und Klartext (Default)
STRICTnur mTLS, Klartext wird abgelehnt
DISABLEkein 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
Stiller Ausfall: Erst in Kiali oder in den Metriken prüfen, ob noch Klartext-Verbindungen existieren, dann auf STRICT umstellen. Sonst fallen Clients ohne Sidecar still aus – etwa Monitoring-Scraper oder Jobs aus anderen Namespaces.
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
Der Unterschied zu zwei Deployments hinter einem Service: Dort bestimmt das Verhältnis der Replicas die Verteilung. Mit Istio ist sie unabhängig von der Replica-Anzahl – 10 % bleiben 10 %, egal ob v3 eine oder zehn Replicas hat.

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
Die Reihenfolge zählt: Regeln werden von oben nach unten ausgewertet, die erste passende gewinnt. Die allgemeine Regel ohne 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
  • timeout ist die Gesamtzeit inklusive aller Retries.
  • Retries nur für idempotente Operationen. Ein wiederholtes POST /bestellung kann 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?

Nach dem Test die Regel wieder entfernen.
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
Sicherung im Stromkreis. Bei Überlast fliegt sie, bevor das ganze Haus abbrennt. Ein Pod, der ständig Fehler wirft, wird für 30 Sekunden vom Netz genommen.

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:

Request kommt an CUSTOM lehnt ab? ja nein DENY passt? ja nein ALLOW-Policies für den Workload vorhanden? nein ja Passt eine? ja nein abgelehnt abgelehnt erlaubt erlaubt abgelehnt Ohne Policies ist alles erlaubt – die erste ALLOW-Policy dreht das um.
Die wichtigste Falle: Ohne Policies ist alles erlaubt. Die erste ALLOW-Policy für einen Workload dreht das um – ab dann ist alles verboten, was nicht explizit erlaubt ist.

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.

Unterschied zur NetworkPolicy: Die kennt nur IP und Port (L3/L4). Eine AuthorizationPolicy kennt Identität, HTTP-Methode, Pfad und Header (L7) und funktioniert unabhängig von IP-Adressen. Kombinierbar: NetworkPolicy als grobe Außenmauer, AuthorizationPolicy als Türschloss.
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
Keine harte Sicherheitsgrenze: Ohne eigenes Egress-Gateway ist das eine Absicherung gegen versehentliche Verbindungen. Ein kompromittierter Pod könnte den Sidecar umgehen. Für echte Durchsetzung zusätzlich NetworkPolicies bzw. EgressFirewall einsetzen, die nur das Egress-Gateway nach außen lassen.
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.

Nicht für Produktion: Die Add-ons aus 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
7

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 principals und 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"]
Häufige Falle: Eine L7-Regel (Methode, Pfad) mit selector statt targetRefs kann der ztunnel nicht auswerten, weil er nur L4 sieht. Die Regel greift dann nicht wie erwartet – istioctl analyze warnt davor.
8

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
Server-first-Protokolle: Bei MySQL und ähnlichen sendet der Server zuerst. Die automatische Erkennung wartet auf die ersten Bytes des Clients und hängt dann. Solche Ports immer als 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/proxyCPU und sidecar.istio.io/proxyMemory.
  • In großen Clustern kennt jeder Proxy standardmäßig alle Services. Die Sidecar-Ressource und discoverySelectors reduzieren 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.
Nicht alles in das Mesh packen: Ein Mesh ist zusätzliche Komplexität – mehr Komponenten, mehr Latenz pro Hop (typisch im niedrigen einstelligen Millisekundenbereich pro Proxy) und mehr Fehlerquellen. Sinnvoll, wenn mehrere der Anforderungen aus Abschnitt 0 zusammenkommen. Wer nur Verschlüsselung will, ist mit Ambient ohne Waypoints gut bedient.

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.

9

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

  1. istioctl analyze -n <ns>Warnungen? Dann zuerst die Konfiguration korrigieren – das erledigt die meisten Fälle.
  2. istioctl proxy-statusAlle SYNCED? Wenn nicht: istiod-Logs prüfen, der Proxy erreicht istiod nicht.
  3. Access-Log des Proxys lesenStatus-Code plus Response-Flag – siehe Tabelle unten.
  4. istioctl proxy-config …Kommt die Regel überhaupt im Proxy an?

Wichtige istioctl-Befehle

BefehlZeigt
istioctl analyze -n <ns>Konfigurationsfehler
istioctl proxy-statusob 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 workloadsAmbient: Workloads und Protokoll

Response-Flags im Access-Log

FlagBedeutungTypische Ursache
NRNo Routekeine Route passt: VirtualService falsch, Host stimmt nicht
UHNo Healthy Upstreamkeine gesunden Pods: alle ausgeworfen oder keine Endpoints
UFUpstream Connection FailuremTLS-Konflikt, App lauscht nicht
UOUpstream OverflowCircuit Breaker hat abgelehnt
URXRetry Limit Exceededalle Retries fehlgeschlagen
UTUpstream TimeoutTimeout aus dem VirtualService erreicht
DCDownstream Connection TerminationClient hat die Verbindung abgebrochen
Häufigster Fall: Ein 503 mit 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
LabelWirkung
istio-injection=enabledSidecar-Injection für den Namespace (nach Pod-Neustart)
istio.io/rev=<revision>Sidecar einer bestimmten Control-Plane-Revision
istio.io/dataplane-mode=ambientNamespace oder Pod in den Ambient-Mesh aufnehmen
istio.io/use-waypoint=<name>Service oder Namespace nutzt diesen Waypoint
PortZweck
15001Envoy: ausgehender Traffic (umgeleitet)
15006Envoy: eingehender Traffic (umgeleitet)
15000Envoy Admin (nur localhost)
15008HBONE-Tunnel (Ambient, mTLS)
15012istiod: xDS und Zertifikate
15017istiod: Webhook
15020Istio-Agent: Metriken, Probe-Umleitung
15021Health-Check des Proxys
15090Envoy-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 analyze nach jeder Änderung.

Mindestablauf für ein neues Projekt

  1. Namespace labelnInjection oder Ambient.
  2. Prüfenistioctl analyze und istioctl proxy-status.
  3. PeerAuthentication auf STRICTsobald alle Clients im Mesh sind.
  4. allow-nothing plus gezielte ALLOW-Policies
  5. Timeouts setzenRetries nur für idempotente Aufrufe.
  6. Kiali und Access-Logs zur Kontrolle