Istio Cheatsheet

Istio CheatsheetKapitel 07 von 10

Istio-Diagnose

Stand Istio 1.31 · Edition 2026.10 · Release-Daten geprüft am 20. Oktober 2026

Erstes istioctl-Werkzeug bei Vorfall

istioctl proxy-status zeigt Sync-Stand jedes Sidecars. SYNCED = ACK erhalten, NOT SENT = nichts zu senden (meist normal), STALE = gesendet, kein ACK → Netz istiod/Proxy oder Bug, ERROR = NACK → Config prüfen.

istioctl proxy-status
istioctl proxy-config routes <pod>.<ns> -o json
istioctl proxy-config clusters <pod>.<ns>
istioctl proxy-config listeners <pod>.<ns>
istioctl proxy-config endpoints <pod>.<ns>
istioctl proxy-config secrets <pod>.<ns>

# Statisches Lint: VirtualService/DR-Konflikte etc.
istioctl analyze -n prod

# Bug-Report: Konfig + Logs,
# Secret-Inhalte nur mit --full-secrets
istioctl bug-report

Live-Log eines Sidecars

istioctl proxy-config log <pod> --level debug setzt das Log-Level live ohne Pod-Restart. Komponenten-spezifisch z.B. --level rbac:debug,jwt:debug. Nach Diagnose zurück auf warning.

Häufige Fehlerbilder

404 NR: keine Route, Host- oder Path-Match greift nicht, Reihenfolge der http[] prüfen.
503 UF: Connect zum Upstream scheitert, App-Port ≠ targetPort oder TLS-Mismatch (DR DISABLE gegen STRICT).
503 UC: Upstream schließt bestehende Verbindung, oft Idle-Timeout der App kürzer als Envoy-Pool.
503 UH: kein gesunder Endpoint (Readiness, Outlier Detection).

OUTPUT_CERTS-Scraping: read: connection reset by peer

App-originated mTLS (Prometheus/Alloy-Federate via ISTIO_META_OUTPUT_CERTS + /etc/istio-certs/{cert-chain,key,root-cert}.pem) bricht mit RST, obwohl Ziel-PeerAuthentication PERMISSIVE ist und Allow-all greift.

Ursache fast immer: Client-Sidecar wrapt den App-mTLS in einen zweiten ISTIO_MUTUAL-Tunnel. Eine DR mit host: "*.local" + exportTo: ["*"] (typisch STRICT-Migration-Helper in istio-system) matcht via EndpointSlice-Lookup auch direkte Pod-IP-Calls. Ergebnis: TLS-in-TLS. Ziel-15006 terminiert nur outer; inner TLS-Bytes landen als Klartext auf dem App-Port, Backend erwartet HTTP, schließt.

PERMISSIVE ist Inbound-Entscheidung nach der Transport-Terminierung und heilt nichts, was outbound passiert.

Fix: excludeOutboundPorts am Scraper-Pod (port-scoped) oder eigene DR mit tls.mode: DISABLE auf den Ziel-Service (spezifischer als *.local, gewinnt).

# wraps der Client-Sidecar?
# alpn=istio* + sni=outbound_ = Beweis:
istioctl pc cluster <pod>.<ns> --fqdn <ziel> -o json \
  | jq '.[]|(.transportSocket,
    .transportSocketMatches[]?.transportSocket)
    |select(.).typedConfig
    |{sni,alpn:.commonTlsContext.alpnProtocols}'
# welche *.local-DR greift?
kubectl get dr -A -o json | jq -r '.items[]|
  select(.spec.host|test("\\*\\.local"))|
  .metadata.namespace+"/"+.metadata.name'