Service Mesh: Istio versus Linkerd, mTLS en verkeersbeheer
In een microservices-architectuur op Kubernetes communiceert elke service met tientallen anderen. Wie garandeert dat deze communicatie gecodeerd is? Wie beheert wanneer de automatische nieuwe poging? een dienst is tijdelijk niet bereikbaar? Wie levert de latentie- en snelheidsstatistieken fouten voor elk bron-bestemmingspaar? Beantwoord deze zonder een servicemesh Voor vragen is in elke service aangepaste code vereist.
Un service netwerk lost deze problemen op infrastructuurniveau op, transparant voor toepassing. De twee dominante spelers in de Kubernetes-omgeving zijn dat wel Istio, de meest veelzijdige, en Linkerd, ontworpen voor eenvoud en minimale overhead. Dit artikel laat zien hoe u het installeert beide, configureer automatische mTLS, beheer verkeer met canary-implementatie en circuitonderbreking en wanneer u het een of het ander moet kiezen.
Wat je gaat leren
- Hoe een servicemesh werkt: datavlak (zijspan) en besturingsvlak
- Automatische mTLS: wat het betekent, hoe u het kunt controleren, hoe u met uitzonderingen moet omgaan
- Istio: installatie, VirtualService, DestinationRule, kanarie en blauw/groen
- Linkerd: lichtgewicht installatie, SMI TrafficSplit, uitbreidingen
- Circuitonderbreking met Istio OutlierDetection
- Opnieuw proberen en time-out op infrastructuurniveau
- Waarneembaarheid: gouden signalenstatistieken uit de servicemesh
- Istio vs Linkerd: wanneer kies je welke?
Hoe een servicemesh werkt
Het servicegaas is gebaseerd op de automatische injectie van a zijspan proxy (Gezant voor Istio, Linkerd2-proxy voor Linkerd) in elke Pod. Het zijspan onderschept alles verkeer in en uit de applicatiecontainer, zonder dat er wijzigingen nodig zijn naar de code.
Il gegevensvlak en de verzameling van alle proxy-zijspannen die het verkeer afhandelen effectief. De controle vlak (Istiod voor Istio, linkerd-control-plane voor Linkerd) distribueert de configuratie naar proxy's, beheert certificaten voor mTLS en verzamelt telemetrie.
Istio versus Linkerd-vergelijking
| Kenmerkend | Istio | Linkerd |
|---|---|---|
| Zijspan-proxy | Gezant (C++, 50-100 MB) | linkerd2-proxy (roest, 10-20 MB) |
| Geheugenoverhead voor Pod | 100-200 MB | 20-30 MB |
| Latentie-overhead P99 | 2-5 ms | 0,5-1 ms |
| Automatische mTLS | Ja (cert-manager of ingebouwd) | Ja (24 uur automatische rotatie) |
| Verkeersmanagement | Volledig (VirtueleService, DR) | Basis (HTTPRoute, TrafficSplit) |
| L7-beleid | HTTP, gRPC, TCP | HTTP, gRPC |
| Ingang | API-gateway + Istio-gateway | API-gateway |
| Leercurve | Stijl | Gematigd |
| Volwassenheid van de productie | Hoog (Google, Airbnb) | Hoog (Shopify, Microsoft) |
Istio: basisinstallatie en configuratie
Installatie met istioctl
# Scarica e installa istioctl
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.22.0 sh -
export PATH=$PWD/istio-1.22.0/bin:$PATH
# Installa Istio con profilo di produzione
istioctl install --set profile=production -y
# Il profilo production abilita:
# - HA con multiple repliche del control plane
# - Affinity rules per distribuire su nodi diversi
# - Risorse CPU/memoria adeguate
# - Solo le feature necessarie (no addon come Kiali, Jaeger)
# Abilita l'iniezione automatica del sidecar nel namespace
kubectl label namespace production istio-injection=enabled
# Verifica lo stato del mesh
istioctl proxy-status
# Analizza la configurazione per possibili problemi
istioctl analyze --namespace production
mTLS met Istio: PeerAuthentication en DestinationRule
Istio implementeert automatische mTLS tussen alle geïnjecteerde zijspanpods. Met PeerAuthenticatie kan worden gedaan via mTLS STRENG (vereist) een naamruimte of volledig meshniveau:
# mtls-strict.yaml
# Abilita mTLS STRICT per tutto il namespace production
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default-mtls
namespace: production
spec:
mtls:
mode: STRICT # DISABLE, PERMISSIVE, STRICT
---
# Eccezione: un servizio legacy che non ha sidecar
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: legacy-service-exception
namespace: production
spec:
selector:
matchLabels:
app: legacy-service
mtls:
mode: PERMISSIVE # accetta anche connessioni plain-text
# Verifica mTLS
kubectl exec -n production frontend-pod -c istio-proxy -- \
pilot-agent request GET /config_dump | grep -A5 "tls_context"
# Visualizza lo stato mTLS con istioctl
istioctl x describe pod frontend-pod.production
VirtualService: routering en verkeerssplitsing
De VirtualService definieert hoe verkeer naar een service wordt gerouteerd, met regels gebaseerd op HTTP-headers, gewichten, padmatching:
# virtual-service-canary.yaml
# Canary deployment: 90% traffico a v1, 10% a v2
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: api-service-vs
namespace: production
spec:
hosts:
- api-service # nome del Kubernetes Service
http:
# Routing per header: dev e QA ricevono sempre v2
- match:
- headers:
x-user-group:
exact: "beta-testers"
route:
- destination:
host: api-service
subset: v2
# Traffico generale: 90/10 split
- route:
- destination:
host: api-service
subset: v1
weight: 90
- destination:
host: api-service
subset: v2
weight: 10
# Timeout e retry a livello di infrastruttura
timeout: 5s
retries:
attempts: 3
perTryTimeout: 2s
retryOn: "5xx,reset,connect-failure,retriable-4xx"
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: api-service-dr
namespace: production
spec:
host: api-service
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http2MaxRequests: 1000
maxRequestsPerConnection: 10
loadBalancer:
simple: LEAST_CONN # ROUND_ROBIN, RANDOM, LEAST_CONN
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
Stroomonderbreker met uitschieterdetectie
De stroomonderbreker verwijdert tijdelijk "ongezonde" hosts uit de taakverdeling pool wanneer ze de gedefinieerde foutdrempels overschrijden:
# destination-rule-circuit-breaker.yaml
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: payment-service-circuit-breaker
namespace: production
spec:
host: payment-service
trafficPolicy:
connectionPool:
tcp:
maxConnections: 50
connectTimeout: 3s
http:
http1MaxPendingRequests: 100
http2MaxRequests: 500
maxRetries: 3
outlierDetection:
# Rimuovi un host se in 10 secondi riceve 5 errori 5xx
consecutiveGatewayErrors: 5
consecutive5xxErrors: 5
interval: 10s
# Tienilo fuori per 30 secondi
baseEjectionTime: 30s
# Massimo 50% degli host puo essere rimosso
maxEjectionPercent: 50
# Analizza solo richieste con 100ms o piu di latenza
minHealthPercent: 50
Istio-gateway voor inkomend verkeer
# istio-gateway.yaml
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: production-gateway
namespace: istio-system
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: wildcard-tls-cert # Secret con cert TLS
hosts:
- "*.federicocalo.dev"
- port:
number: 80
name: http
protocol: HTTP
tls:
httpsRedirect: true # redirect tutto HTTP a HTTPS
hosts:
- "*.federicocalo.dev"
---
# Collega il Gateway al VirtualService
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: api-gateway-vs
namespace: production
spec:
hosts:
- "api.federicocalo.dev"
gateways:
- istio-system/production-gateway
- mesh # anche per traffico interno al mesh
http:
- route:
- destination:
host: api-service
port:
number: 8080
Autorisatiebeleid: toegangscontrole
# authorization-policy.yaml
# Solo il frontend puo chiamare il backend
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: backend-access-policy
namespace: production
spec:
selector:
matchLabels:
app: backend
action: ALLOW
rules:
- from:
- source:
principals:
- "cluster.local/ns/production/sa/frontend-service-account"
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/v1/*"]
---
# Blocca tutto il resto (default deny)
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: deny-all
namespace: production
spec:
action: DENY
# Nessun selector = si applica a tutti i Pod nel namespace
# Nessuna rule = blocca tutto
Linkerd: Installatie en Configuratie
Linkerd is voorstander van operationele eenvoud en prestaties. De proxy is geschreven in Rust Het heeft een overhead van ~1ms P99-latentie en ~20MB geheugen per Pod, waardoor het ideaal is voor clusters met veel microservices of resourcebeperkingen.
Linker installatie
# Installa Linkerd CLI
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh
export PATH=$HOME/.linkerd2/bin:$PATH
# Prerequisiti: verifica che il cluster sia compatibile
linkerd check --pre
# Installa il control plane
linkerd install --crds | kubectl apply -f -
linkerd install | kubectl apply -f -
# Verifica installazione
linkerd check
# Abilita injection sul namespace
kubectl annotate namespace production linkerd.io/inject=enabled
# Installa l'estensione Viz per osservabilita
linkerd viz install | kubectl apply -f -
linkerd viz check
linkerd viz dashboard &
Canarische met Linkerd en HTTPRoute (Gateway API)
# linkerd-canary-httproute.yaml
# Linkerd usa la Gateway API per il traffic splitting
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-service-canary
namespace: production
spec:
parentRefs:
- name: api-service
kind: Service
group: core
port: 80
rules:
- backendRefs:
- name: api-service-v1
port: 80
weight: 90
- name: api-service-v2
port: 80
weight: 10
# Monitora il canary con linkerd viz
linkerd viz stat httproute/api-service-canary -n production
linkerd viz routes deploy/api-service-v2 -n production
Waarneembaar bij Linkerd
# Visualizza metriche golden signals per tutti i deployment
linkerd viz stat deploy -n production
# Output tipico:
# NAME MESHED SUCCESS RPS LATENCY_P50 LATENCY_P99 TCP_CONN
# api-service 4/4 99.8% 245 1ms 12ms 42
# backend-service 3/3 98.2% 180 3ms 45ms 28
# payment-service 2/2 100.0% 65 8ms 89ms 12
# Visualizza il traffico per un singolo Pod
linkerd viz tap pod/api-service-xyz -n production
# Genera un report di osservabilita
linkerd viz check --proxy -n production
Istio-telemetrie: statistieken, tracering en logboekregistratie
Istio geeft automatisch de gouden signalen (latentie, verkeer, fouten, verzadiging) voor elk bron-bestemmingspaar. Metrieken worden weergegeven in formaat Prometheus en zichtbaar in Grafana met de officiële Istio-dashboards.
# telemetry-config.yaml
# Configura il sampling per il distributed tracing
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
name: mesh-tracing
namespace: istio-system
spec:
tracing:
- providers:
- name: tempo # o jaeger, zipkin
randomSamplingPercentage: 1.0 # campiona 1% del traffico in produzione
---
# Metriche custom per un servizio specifico
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
name: payment-service-metrics
namespace: production
spec:
selector:
matchLabels:
app: payment-service
metrics:
- providers:
- name: prometheus
overrides:
- match:
metric: REQUEST_COUNT
tagOverrides:
destination_version:
value: "request.headers['x-version'] | 'unknown'"
# Importa le dashboard Grafana ufficiali Istio
# Dashboard ID: 7639 (Mesh Overview), 11829 (Service), 12378 (Workload)
Service Mesh versus Cilium eBPF: wanneer moet u ze gebruiken?
Met de komst van Cilium, dat mTLS- en L7-beleid aanbiedt zonder zijspannen (via eBPF in de kernel), de keuze is ingewikkeld. Hier is een praktische gids:
| Scenario | Aanbevolen keuze | Reden |
|---|---|---|
| Microservices met geavanceerd verkeersbeheer (canary, header-based routing) | Istio | VirtualService/DestinationRule onvervangbaar |
| mTLS-beveiliging met minimale overhead | Linkerd of Cilium | Roestproxy of minimale eBPF |
| Cluster met honderden microservices, beperkte middelen | Linkerd of Cilium mTLS | Zijspanoverhead vermenigvuldigd met elke Pod |
| Multicluster of multicloud | Istio | Meshfederatie ingebouwd |
| Team nieuw bij service mesh | Linkerd | Aanzienlijk lagere leercurve |
Best practices voor servicemesh
Checklist voor servicemesh in productie
- Start in de TOEGESTAANE modus: schakel mTLS in PERMISSIVE in voordat u het STRIKT maakt, om services te identificeren die nog geen zijspan hebben
- Time-out instellen voor alle VirtualServices: zonder time-out blokkeert een langzame afhankelijkheid de hele oproepketen
- Stroomonderbreker voor elke externe afhankelijkheid: databases, externe API's, betalingsdiensten
- Gebruik opnieuw proberen alleen voor idempotente fouten: doe geen automatische nieuwe poging op POST zonder idempotentiesleutel, anders creëer je dubbele bestellingen
- Monitor CPU/geheugen zijspan: in clusters met veel Pods kan de totale zijspanoverhead aanzienlijk zijn
- Failover testen: schakel een pod handmatig uit en controleer of de stroomonderbreker en nieuwe pogingen werken zoals verwacht
- Houd de mesh bijgewerkt: Istio- en Linkerd-versies hebben een korte levenscyclus (6-12 maanden); plan regelmatig upgrades
Veelvoorkomende antipatronen
- Oneindige nieuwe pogingen met versterking: als A B terugroept met 3 nieuwe pogingen, en B C terugroept met 3 nieuwe pogingen, genereert een enkele fout 9 pogingen richting C (nieuwe poging storm)
- Te genereuze time-outs: een time-out van 60 seconden op een kritieke API betekent dat tijdens een storing alle applicatiethreads/goroutines gedurende 60 seconden worden geblokkeerd
- Controlevlak boven het hoofd negeren: Istiod verbruikt aanzienlijk CPU/geheugen voor elke verbonden proxy; in clusters met meer dan 1000 pods is een speciaal knooppunt nodig
- Selectieve injectie zonder vlak: als slechts enkele Pods zijspannen hebben, mislukt mTLS STRICT voor communicatie met Pods zonder zijspannen
Conclusies en volgende stappen
Service mesh is niet langer een ‘nice to have’, maar is een vereiste geworden elke serieuze microservices-architectuur. Automatische mTLS, gedetailleerde waarneembaarheid, circuitonderbreking en declaratief verkeersmanagement lossen echte problemen op zonder een servicemesh zou in elke service aangepaste code vereisen.
De keuze tussen Istio en Linkerd hangt af van uw wensen: Istio voor complexe scenario's met geavanceerd en multi-cluster verkeersbeheer, Linkerd voor operationele eenvoud en overhead minimaal. In beide gevallen gaat het om de initiële investering in leren en instellen en zijn vruchten afgeworpen door de vermindering van infrastructurele code in toepassingen en zichtbaarheid ongekende impact op het intraclusterverkeer.
Aankomende artikelen in de Kubernetes at Scale-serie
Vorige artikelen
Gerelateerde serie
- Kubernetes-netwerken: Cilium met eBPF — alternatief voor service mesh voor mTLS
- Waarneembaarheid en OpenTelemetrie — gedistribueerde tracering geïntegreerd met Istio
- Platformtechniek — service mesh als intern platform







