Service Mesh Cheatsheet

Service Mesh CheatsheetAlle Kapitel

Service Mesh Cheatsheet im Volltext

Stand Istio 1.31, Cilium 1.20, Linkerd edge-26.10.x, Kuma 3.0, Consul 2.1 · Edition 2026.11

Cheatsheet im Volltext

Derselbe Inhalt wie im PDF, zum Mitlesen, Durchsuchen und direkten Kopieren der YAML-Snippets. Tool-agnostischer Vergleich: Istio (Sidecar + Ambient), Linkerd, Cilium, Kuma, Consul. Stand: 30. Oktober 2026 (Edition 2026.11).

Tools im Vergleich

Die drei Patterns

Sidecar (Istio classic, Linkerd, Kuma, Consul): Envoy bzw. linkerd2-proxy neben jedem App-Container, heute als native Sidecar (Linkerd 2.20: Default; Istio: Default ENABLE_NATIVE_SIDECARS=auto, aktiv ab Kubelet 1.33). Mature, transparent, Memory-Kosten.

Sidecar-less / eBPF (Cilium): L3/L4 im Kernel, Identity per Pod-Label, kein per-Pod-Datenpfad. L7 via Envoy als shared proxy (cilium-envoy DaemonSet).

Ambient (Istio, GA seit 1.24): ztunnel als Node-Agent (L4/mTLS), Waypoint-Proxy on-demand (L7). Sidecarless ohne Kernel-Pfad.

Auswahl: was wann

Stand 10/2026: Istio 1.31, Cilium 1.20, Linkerd edge-26.10.x (Meilenstein 2.20), Kuma 3.0, Consul 2.1.

Istio (Sidecar): größtes Ecosystem, alle L7-Features, Multi-Cluster mature, ein Envoy je Pod.

Istio (Ambient): Multi-Cluster nur Multi-Primary mit Multi-Network (Beta seit 1.29, Single-Network ungetestet), kein Primary-Remote, keine VMs, kein SPIRE.

Linkerd: schlank, Rust-Proxy, kein Wasm, kein eigener Ingress. Multi-Cluster per Extension (Gateway, Flat Network, Federated).

Linkerd, Beschaffungs-Kriterium: das Open-Source-Projekt liefert seit 02/2024 keine Stable-Artefakte mehr. Frei sind nur die wöchentlichen edge-Releases; Stable-Builds kommen von Vendoren (Buoyant Enterprise for Linkerd). Für regulierte Umgebungen ist das eine Vertrags-, keine Technikfrage.

Cilium Service Mesh: wenn CNI eh Cilium ist. Identity am Kernel, eBPF-Observability. L7 über den Envoy pro Node, nicht pro Pod.

Kuma (CNCF Sandbox, Apache 2.0): Envoy-Sidecar auf Kubernetes und VMs, Multi-Zone mit globaler Control Plane. mTLS per MeshIdentity/MeshTrust (SPIFFE-IDs, eigene CA oder SPIRE), Routing per MeshHTTPRoute oder HTTPRoute/GRPCRoute. 3.0 (15.10.2026) entfernt die Legacy-Policies, Mesh.mtls und das eingebaute Gateway.

Consul (HashiCorp, BUSL 1.1 seit 1.17, kein CNCF-Projekt): Envoy-Sidecar auf Kubernetes, VMs, Nomad und ECS. Zugriff per Intentions (L4 oder L7), Routing per Config-Entries service-router, -splitter, -resolver; Gateway-API-Ressourcen nur am API-Gateway dokumentiert.

Datapath / Ressourcen

Sidecar: zwei Proxy-Durchläufe je Request (Client- und Server-Pod). Ambient: zwei ztunnel-Hops (Quell- und Ziel-Node), Waypoint nur als zusätzlicher Hop, wenn L7 greift. Cilium: L3/L4 ohne Proxy, L7-Regeln leiten über den Node-Envoy.

Istio-Benchmark (1.24, 1000 req/s, 1 KB): Sidecar ∼0,20 vCPU und 60 MB, Waypoint ∼0,25 vCPU und 60 MB, ztunnel ∼0,06 vCPU und 12 MB.

Traffic Management

Routing-APIs im Vergleich

Istio: VirtualService + DestinationRule (eigene CRDs), mächtig, aber zwei Konzepte: Match/Route vs. Subset/LB/CB. In Ambient ist VirtualService nur Alpha, dort HTTPRoute.

Linkerd: HTTPRoute/GRPCRoute; Retries und Timeouts per Annotation (retry.linkerd.io/http, timeout.linkerd.io/request) seit 2.16, Timeouts auch per Feld timeouts.request. ServiceProfile nur noch Legacy.

Cilium: HTTPRoute/GRPCRoute inkl. GAMMA, nur Producer-Routes (Route im Namespace des Service), Feintuning per CiliumEnvoyConfig. Policy getrennt in CiliumNetworkPolicy (L3–L7).

Konvergenz-Punkt: Gateway API v1.x, Ost-West als GAMMA (Route mit Service als parentRef). Consumer-Routes (Route im Namespace des Clients): Istio und Linkerd ja, Cilium nein. CRDs sind clusterweit, aktuell ist v1.7.0 (29.10.2026): Istio 1.31 dokumentiert v1.6.0, Cilium 1.20 (mit Gateway-API-Support) verlangt ≥ v1.6.1, Linkerd 2.20 ist bis v1.5.1 freigegeben. v1.7 hebt retry an der HTTPRoute in den Standard-Channel: Istio setzt das Feld um, Linkerd liest Retries nur aus der Annotation.

# GAMMA-HTTPRoute (Ost-West; Istio Ambient: nur mit Waypoint)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata: {name: api, namespace: prod}
spec:
  parentRefs:
  - {group: "", kind: Service, name: api, port: 8080}
  rules:
  - matches: [{path: {type: PathPrefix, value: /v2}}]
    backendRefs: [{name: api-v2, port: 8080}]
  - backendRefs: [{name: api, port: 8080}]

Traffic-Split / Canary

Istio: VirtualService.http[].route[].weight.

Linkerd: HTTPRoute backendRefs[].weight.

Cilium: HTTPRoute mit weighted backends, alternativ mit Flagger/Argo-Rollouts auf Istio, Linkerd und Cilium.

Egress & Circuit-Breaking

Istio: ServiceEntry für externe Ziele, outlierDetection und connectionPool in DestinationRule.trafficPolicy, ab 1.31 meshweite Baseline per meshConfig.defaultTrafficPolicy.

Linkerd: EgressNetwork-CRD (2.17+) für Egress-Sicht und -Policy. Circuit-Breaking (2.13+) per Service-Annotation balancer.linkerd.io/failure-accrual.

Cilium: FQDN-Policy (toFQDNs) für Egress. Circuit-Breaking nur über rohe Envoy-Konfiguration (CiliumClusterwideEnvoyConfig).

Security & Identity

mTLS & Identity

Istio: SPIFFE-Identity (spiffe://td/ns/X/sa/Y), istiod als CA, automatische Cert-Rotation. PeerAuthentication STRICT pro Namespace. FIPS 140-3 ab 1.31: COMPLIANCE_POLICY=fips-140-3 (TLS 1.2+/AES-GCM, P-256/P-384), davor als FIPS-Profil nur fips-140-2.

Linkerd: linkerd-identity als CA, Identity per ServiceAccount, mTLS by default ohne Opt-in (sobald beide Pods im Mesh sind). Trust Anchor aus linkerd install läuft nach 365 Tagen ab: selbst erzeugen, Issuer per cert-manager rotieren.

Cilium: Identity per Pod-Labels, nicht ServiceAccount. Mutual Auth (SPIFFE, Beta seit 1.14) ist seit 1.20 abgekündigt; bis 1.19.5, 1.18.11 und 1.17.17 konnte damit, wer ein gültiges Client-Zertifikat hatte, jede Identität imitieren (GHSA-33qq-jq9c-6gcc, 1.14 bis 1.16 ohne Fix). Nachfolger: ztunnel-Encryption (Beta seit 1.19, Namespace-Label io.cilium/mtls-enabled=true, nicht mit ClusterMesh).

Öffentlicher Trust Store (eMudhra-Intermediates, 10/2026): Mesh-mTLS läuft über die mesheigene CA und ist nicht betroffen. Betroffen ist nur, was dem öffentlichen CA-Bundle vertraut: TLS-Origination und Egress zu externen Hosts (Istio: DestinationRule mit SIMPLE ohne caCertificates), JWKS-Abruf durch istiod. Fix: Istio 1.31.3 und 1.30.7, Cilium 1.20.4, 1.19.10 und 1.18.16. Linkerd edge-26.10.2 baut mit Go 1.26.10; bei Consul 2.1.0 (1.26.10) und Kuma 3.0.1 (1.27.3) deckt Go nur die Go-Teile ab, nicht das CA-Bundle der Envoy-Images.

Authorization-Policy

Istio: AuthorizationPolicy mit action: ALLOW | DENY | AUDIT | CUSTOM. JWT: RequestAuthentication validiert, AuthorizationPolicy erzwingt (requestPrincipals, when). In Ambient greifen L7-Regeln nur am Waypoint (targetRefs); gegen Umgehung gehört eine ztunnel-Policy dazu, die nur die Waypoint-Identität zulässt. Ingress-Gateways umgehen den Waypoint per Default: L7-Policies am Waypoint greifen für Nord-Süd-Traffic erst mit istio.io/ingress-use-waypoint=true am Service (am Namespace ab 1.25). DENY-Regeln mit methods (und ALLOW mit notMethods) ließen sich über HTTP/2 durch abweichende Groß-/Kleinschreibung der Methode umgehen, Fix ab 1.31.2 und 1.30.6 (ISTIO-SECURITY-2026-007; dessen CVSS 9.2 gilt einer Brotli-Lücke in Envoy).

Linkerd: AuthorizationPolicy auf Server oder HTTPRoute, ServerAuthorization ist die ältere Form. Default-deny per Annotation config.linkerd.io/default-inbound-policy: deny. Vor edge-26.9.1 verfehlte ein Host-Header in anderer Schreibweise eine hostnamegebundene HTTPRoute und fiel auf eine breitere Route mit deren Policy durch (GHSA-7cq8-3jwj-3pcf). Vor edge-26.6.2 blieb eine gelöschte MeshTLSAuthentication wirksam (GHSA-229q-25q4-rxm8).

Cilium: L7-Rules in CiliumNetworkPolicy (HTTP-Method, Path, Header). JWT nicht nativ.

Kuma: MeshTrafficPermission mit Matches auf spiffeID oder sni. Consul: Intentions.

# Istio: default-deny + selektive Erlaubnis
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata: {name: deny-all, namespace: prod}
spec: {}                       # leere Rules = deny
---
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata: {name: allow-api, namespace: prod}
spec:
  selector: {matchLabels: {app: api}}
  rules:
  - from: [{source: {principals:
      ["cluster.local/ns/web/sa/frontend"]}}]

Observability

Was du out-of-the-box bekommst

Istio: Telemetry-API (Metriken, Tracing, Logs) mit Provider-Konfiguration. Prometheus + Kiali + Jaeger als Standard-Stack.

Linkerd: viz-Extension (Dashboard, tap, stat); deren Prometheus hält nur 6 h, produktiv extern. Tracing per OpenTelemetry (2.17+), Collector muss im Mesh laufen, linkerd-jaeger ist seit 2.19 abgekündigt und nicht mehr verfügbar.

Cilium: Hubble (eBPF-basiertes Flow-Logging), Hubble UI für Service-Map. Metriken in Prometheus, Tracing extern.

Pflicht-Metriken

Golden Signals: Requests/s, Errors/s, Latency-p50/p95/p99 (istio_requests_total, istio_request_duration_milliseconds, linkerd: response_latency_ms_bucket, je Route outbound_http_route_request_duration_seconds).

Saturation: Sidecar-CPU/Memory, xDS-Push-Latenz (Istio: pilot_xds_push_time), Hubble: hubble_drop_total.

Tracing-Falle

Jedes Mesh braucht App-Header-Propagation (b3, traceparent). Ohne das zerreißt der Span-Tree beim ersten App-zu-App-Hop. Kein Mesh kann das auf L7 simulieren.

Multi-Cluster

Topologien

Istio: Primary-Remote (ein istiod, Workload-Cluster ohne Control-Plane) | Multi-Primary (istiod pro Cluster, gemeinsame Root-CA) | External Control-Plane. Pflicht: gemeinsame trustDomain oder trustDomainAliases. Ambient: nur Multi-Primary; Ambient-Multi-Cluster laut Projekt nicht in einer bestehenden Sidecar-Produktion aktivieren.

Linkerd: multicluster extension mit Service-Mirror, Gateway-basiert, Flat Network ohne Gateway (2.14+) oder Federated Services (2.17+), ein gemeinsamer Trust Anchor. linkerd multicluster check las die Secrets aller Links clusterweit als Kubeconfig: wer im eigenen Namespace Link und Secret anlegen darf, brachte so Code auf den Admin-Rechner (GHSA-7hx9-xmmq-23f3, kritisch, Fix ab edge-26.9.1).

Cilium: ClusterMesh, eBPF-direct-routing zwischen Clustern (kein Gateway-Hop) bei Cilium-CNI auf allen Clustern.

Trust-Domain-Falle

Verschiedene Trust-Domains ⇒ mTLS-Reject zwischen Clustern. Migration: trustDomainAliases im Quell-Cluster setzen, bevor neue Workloads deployt werden, dann switchen. Ab Istio 1.31 lässt sich in AuthorizationPolicy direkt per source.trustDomains / notTrustDomains filtern.

Performance & Tuning

Sidecar-Sizing

Envoy (Istio): Speicher wächst mit der Zahl der Listener, Cluster und Routen, also mit dem Sidecar-Scope (Messwerte: Datapath-Box). Pflicht: Sidecar-Resource pro Namespace, sonst bekommt jeder Proxy die Config aller Services.

linkerd2-proxy: keine veröffentlichten Richtwerte, selbst messen.

ztunnel (Ambient): ein Pod je Node (DaemonSet), Kosten skalieren mit Nodes statt Pods.

Push-Storm-Vermeidung

Istio: Sidecar.egress.hosts einschränken, ab 1.31 auch per Ausschluss (*/* plus ~ns1/*). Delta-xDS ist seit 1.22 Default. Ambient ab ∼40.000 Workloads: ISTIO_GPRC_MAXRECVMSGSIZE an istiod anheben.

Linkerd: kein Full-Push. Jeder Proxy abonniert je Ziel einen Stream (destination.Get) und bekommt nur Deltas aus EndpointSlices. Engpass ist der Speicher des Destination-Controllers bei hohem Pod-Churn (2.20: in Einzelfällen fast 85 % weniger).

Cilium: L3/L4 ohne xDS (BPF-Maps), L7-Konfiguration bekommt der Node-Envoy per xDS vom Agent. cilium-agent-CPU bei vielen Identities prüfen.

Migration & Co-Existence

Sidecar → Ambient (Istio)

Per Namespace, umkehrbar: bei L7-Bedarf Waypoint deployen und per istio.io/use-waypoint aktivieren, dann Label istio.io/dataplane-mode=ambient, Injection-Label entfernen, zuletzt kubectl rollout restart. Vorher VirtualService → HTTPRoute, L7-AuthorizationPolicy per targetRefs an den Waypoint. Mit L7-Policies kein Zero-Downtime: zwischen Löschen und Neuanlage greifen sie nicht. Sidecar-Clients umgehen den Waypoint, EnvoyFilter geht dort nicht.

mTLS-STRICT-Migration

Istio: PERMISSIVE, dann prüfen: reporter="destination", connection_security_policy!="mutual_tls" muss 0 sein, erst dann STRICT.

Linkerd: Default all-unauthenticated, Ziel all-authenticated per config.linkerd.io/default-inbound-policy; wirkt erst beim Pod-Neustart.

Cilium (ztunnel): kein Permissive-Modus, Verkehr zwischen enrollten und nicht enrollten Pods geht nicht. Kommunikationspartner gemeinsam enrollen.

Kuma: MeshTLS mit mode: Permissive, dann Strict.

Ohne Prüfschritt (Istio) brechen Jobs, externe Health-Checks, Legacy-Clients.

Tool-Wechsel

Co-Existence im selben Cluster ist möglich, schmerzhaft: unterschiedliche Pod-Labels, getrennte Namespaces, kein Mesh-zu-Mesh-mTLS. In der Praxis: das neue Mesh in neuen Namespaces einführen, Workloads namespace-weise migrieren, das alte Mesh am Ende entfernen.

Anti-Patterns

Was du nicht tun solltest

Mesh für kleine Cluster (<20 Services): Komplexität > Nutzen, NetworkPolicy + cert-manager reichen.

EnvoyFilter / Wasm als Default-Tool (Istio): erst Telemetry-API + AuthorizationPolicy. EnvoyFilter bricht zwischen Istio-Minors.

VirtualService und HTTPRoute für dieselbe Workload: in Ambient ausdrücklich nicht unterstützt (undefiniertes Verhalten). Pro Workload eine API.

Linkerd ohne Default-Policy: Cluster-Default ist all-unauthenticated. Ein Server ohne Regeln blockt dagegen alles (accessPolicy: deny), Probes nur automatisch erlaubt, solange keine Route am Server hängt.

Cilium-L7-Policy ohne Hubble: der Audit-Mode deckt nur L3/L4 ab, L7-Denies sieht man erst in den Hubble-L7-Flows.

Linkerd neben Gateway API v1.6: der Standard-Channel serviert TCPRoute/TLSRoute nur noch als v1. Linkerd liest TCPRoute nur als v1alpha2 und überspringt sie bis auf eine Log-Warnung, TLSRoute erst ab edge-26.8.4. Die CRDs aus linkerd-crds (v1.1.1; nur mit installGatewayAPI=true, seit 2.19 aus) blockt die safe-upgrades-Policy der Gateway API.

Gateway API v1.7 ohne Blick auf Retries (Istio, für retry aus dem Experimental-Channel): die neue CRD setzt retry.attempts standardmäßig auf 1, Istio nahm ohne Angabe 2. Eine HTTPRoute mit retry ohne attempts wiederholt dann einmal statt zweimal.

Projekte und Quellen