Un service mesh injecte un proxy dans chaque pod pour intercepter tout le trafic entre services, sans changer une ligne de code applicatif. Ce que ce proxy apporte gratuitement (mTLS, retries, observabilité L7) a un coût réel en complexité opérationnelle, et ce coût diffère radicalement entre Istio et Linkerd.
Ce qu’un service mesh résout que Kubernetes ne résout pas
Un objet Service route le trafic vers des pods sains, mais ne dit rien du contenu de ce trafic : pas de chiffrement automatique entre pods, pas de retry en cas d’échec transitoire, pas de visibilité sur les codes de statut HTTP ou les latences par requête. Une NetworkPolicy filtre qui peut parler à qui, mais au niveau IP et port, jamais au niveau applicatif. Le service mesh comble cet écart en interceptant chaque appel via un proxy sidecar, sans toucher au code : chiffrement TLS mutuel entre tous les pods du mesh, métriques de latence et de taux d’erreur par paire de services, retries et timeouts configurables en dehors du code applicatif.
# Sidecar injecté automatiquement dans chaque pod du namespace,
# le code applicatif ne voit jamais ce proxy
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
istio-injection: enabled
Istio : maximum de fonctionnalités, maximum de surface
Istio construit son plan de données sur des proxies Envoy, un proxy généraliste extrêmement riche en fonctionnalités : répartition de trafic pondérée pour du canary release, injection de fautes pour tester la résilience, autorisation fine par règle. Ce même Envoy consomme un CPU et une mémoire non négligeables par pod, et le plan de contrôle (istiod) devient lui-même un composant critique supplémentaire à surveiller, mettre à jour et dimensionner.
# VirtualService Istio : 90% du trafic vers v1, 10% vers v2,
# une primitive que Kubernetes seul n'offre pas nativement
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: my-app
spec:
hosts:
- my-app
http:
- route:
- destination: {host: my-app, subset: v1}
weight: 90
- destination: {host: my-app, subset: v2}
weight: 10
Le mode ambient, plus récent, retire le sidecar par pod au profit d’un proxy partagé par nœud (ztunnel), réduisant la surcharge en échange d’une isolation par pod plus faible : un compromis à évaluer selon le niveau de confiance entre workloads d’un même nœud.
Linkerd : le strict nécessaire, en Rust
Linkerd fait le choix inverse : un micro-proxy écrit en Rust (linkerd2-proxy), conçu spécifiquement pour ce rôle plutôt que détourné d’un proxy généraliste, avec une empreinte mémoire et CPU nettement plus légère qu’Envoy. Le mTLS est activé par défaut dès l’injection, sans configuration explicite à écrire : le choix inverse d’Istio, qui expose davantage de leviers mais n’active rien par défaut.
# mTLS actif dès l'injection, aucune ressource
# supplémentaire à écrire pour l'obtenir
linkerd inject deployment.yaml | kubectl apply -f -
La contrepartie est un périmètre fonctionnel plus restreint : pas de répartition de trafic pondérée aussi fine, pas d’injection de fautes, pas de passerelle d’API intégrée. Pour une équipe qui veut du mTLS et de l’observabilité sans piloter un plan de contrôle supplémentaire, cette simplicité est le point ; pour une équipe qui a besoin de règles de routage sophistiquées, c’est une limite réelle.
Le vrai coût : la dette opérationnelle, pas la licence
Les deux projets sont open source et gratuits à l’usage : le coût qui décide en pratique est le temps d’exploitation. Chaque sidecar ajoute de la latence (quelques millisecondes par saut, mais cumulatives sur un appel qui traverse plusieurs services), consomme des ressources qui s’additionnent au nombre de pods, et introduit un composant de plus à mettre à jour à chaque montée de version de Kubernetes. Un mesh mal dimensionné ou jamais mis à jour devient une dette silencieuse, invisible jusqu’à l’incident qui révèle un sidecar en version obsolète, incompatible avec le reste du cluster.
À retenir
Un service mesh apporte du mTLS et de l’observabilité L7 sans toucher au code applicatif, un vrai gain pour un système multi-services. Istio maximise les fonctionnalités (routage pondéré, injection de fautes) au prix d’un plan de contrôle plus lourd à opérer ; Linkerd maximise la simplicité et la légèreté, au prix d’un périmètre fonctionnel plus restreint. Le critère qui tranche n’est ni la licence ni le nom du projet, mais la capacité réelle de l’équipe à opérer un composant de plus sur la durée, un arbitrage qui s’inscrit dans la même logique que celui posé pour l’industrialisation d’une chaîne CI/CD.