TL;DR — Résumé Rapide
Guide complet Envoy Proxy pour service mesh et edge proxy. Couvre xDS API, équilibrage de charge, mTLS, observabilité, circuit breaking et sidecar Kubernetes.
Envoy Proxy est le plan de données au cœur des service meshes modernes. Créé à l’origine chez Lyft pour résoudre l’observabilité et la fiabilité des microservices à grande échelle, Envoy est aujourd’hui le sidecar de facto pour Istio, l’edge proxy de nombreux contrôleurs d’ingress et un proxy L3/L4/L7 polyvalent utilisé par Google, AWS et des milliers d’entreprises. Ce guide couvre l’architecture d’Envoy, la configuration statique et dynamique, les algorithmes d’équilibrage de charge, le pipeline d’observabilité, la gestion TLS et les filtres avancés.
Prérequis
- Docker (pour les tests autonomes) ou un cluster Kubernetes.
- Connaissance de base de HTTP, TLS et des concepts de proxy inverse.
- Familiarité avec la syntaxe de configuration YAML.
curlet optionnellementjqpour tester les endpoints.
Architecture d’Envoy
Envoy fonctionne comme un proxy réseau hors processus — il s’exécute à côté de votre application plutôt que comme une bibliothèque à l’intérieur. Cela rend le proxy indépendant du langage et permet des mises à jour indépendantes.
Composants principaux :
- Listeners — Ports réseau sur lesquels Envoy écoute (les connexions downstream arrivent ici).
- Chaînes de filtres — Liste ordonnée de filtres réseau et HTTP appliqués à chaque connexion.
- Clusters — Groupes nommés d’endpoints upstream (vos services backend).
- Endpoints — Paires IP:port individuelles au sein d’un cluster, découvertes via EDS ou config statique.
- Routes — Règles mappant les requêtes entrantes vers des clusters selon le chemin, l’en-tête ou les paramètres de requête.
Modèle de threads : Envoy utilise un thread principal pour la gestion plus un thread worker par cœur CPU. Chaque thread worker gère les connexions indépendamment avec de l’I/O non bloquant. Aucune contention de verrou sur le chemin critique — chaque worker a son propre pool de connexions.
Hot restart : Envoy prend en charge les mises à jour binaires sans interruption via un handshake en mémoire partagée entre l’ancien et le nouveau processus. Le nouveau processus prend en charge les connexions existantes sans perdre de trafic.
Configuration Statique (envoy.yaml)
La façon la plus rapide de démarrer est une configuration YAML statique avec toutes les ressources définies inline :
admin:
address:
socket_address:
address: 0.0.0.0
port_value: 9901
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: service_backend
timeout: 15s
retry_policy:
retry_on: "5xx,reset,connect-failure"
num_retries: 3
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: service_backend
connect_timeout: 0.5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service_backend
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: backend-service
port_value: 8080
health_checks:
- timeout: 1s
interval: 10s
unhealthy_threshold: 2
healthy_threshold: 2
http_health_check:
path: /health
Le bloc admin expose l’API de gestion d’Envoy sur le port 9901. Utilisez-le pour interroger /stats, /clusters, /config_dump et /healthcheck/fail pour les tests de circuit-breaker.
Configuration Dynamique : L’API xDS
Les configurations statiques fonctionnent pour les déploiements simples mais deviennent difficiles à gérer à grande échelle. Le protocole xDS (x Discovery Service) d’Envoy permet à un plan de contrôle de pousser des changements de configuration au moment de l’exécution — sans rechargement, sans redémarrage.
Types de ressources xDS :
| API | Gère |
|---|---|
| LDS (Listener Discovery Service) | Listeners et chaînes de filtres |
| RDS (Route Discovery Service) | Virtual hosts et tables de routes |
| CDS (Cluster Discovery Service) | Définitions de clusters et politiques |
| EDS (Endpoint Discovery Service) | Santé individuelle des endpoints IP:port |
| SDS (Secret Discovery Service) | Certificats TLS et clés privées |
ADS (Aggregated Discovery Service) : Combine toutes les APIs xDS en un seul stream gRPC bidirectionnel. C’est le mode recommandé car il garantit l’ordre — un nouveau cluster est toujours livré avant la route qui le référence, évitant les erreurs 503 temporaires lors des mises à jour.
Delta xDS : Au lieu d’envoyer l’état complet à chaque mise à jour, le delta xDS n’envoie que les ressources ajoutées, modifiées ou supprimées. Essentiel pour les grandes mailles avec des milliers de clusters.
Algorithmes d’Équilibrage de Charge
Envoy prend en charge six politiques d’équilibrage de charge sélectionnables par cluster :
| Politique | Meilleur Pour |
|---|---|
ROUND_ROBIN | Capacité uniforme du backend, choix par défaut |
LEAST_REQUEST | Durée variable des requêtes, évite les backends surchargés |
RING_HASH | Hash cohérent — affinité de cache, services avec état |
RANDOM | Simple, faible overhead, résistant aux endpoints lents |
MAGLEV | Hash cohérent de Google — distribution plus uniforme |
CLUSTER_PROVIDED | Délègue la décision au type de cluster upstream |
Observabilité
Envoy est dogmatique sur l’observabilité — il a été conçu pour rendre les systèmes distribués déboguables. Trois piliers intégrés :
Statistiques : Envoy émet des milliers de compteurs, jauges et histogrammes. Exposez-les à Prometheus via l’endpoint admin :
curl http://localhost:9901/stats/prometheus
Traçage Distribué : Envoy génère et propage automatiquement les en-têtes de contexte de traçage pour Jaeger, Zipkin et OpenTelemetry. Votre application n’a qu’à transmettre ces en-têtes — Envoy gère la création des traces.
Journalisation des Accès : Journaux d’accès JSON structurés avec toutes les métadonnées de requête, incluant le cluster upstream, la durée, le code de réponse et les octets envoyés.
TLS et mTLS avec SDS
Le Secret Discovery Service (SDS) d’Envoy résout la distribution manuelle de certificats : les certificats sont récupérés d’un plan de contrôle au moment de l’exécution et renouvelés sans redémarrage du processus.
Pour le TLS mutuel entre services, le champ match_subject_alt_names applique l’identité SPIFFE — seules les connexions de services avec l’URI SPIFFE attendu sont acceptées. C’est ainsi qu’Istio implémente les réseaux zero-trust : chaque connexion pod à pod est mutuellement authentifiée via des certificats de courte durée renouvelés par SPIRE.
Filtres Avancés
Circuit Breaking : Prévient les défaillances en cascade en limitant les requêtes en attente, les nouvelles tentatives et les connexions. Configurez max_connections, max_pending_requests, max_requests et max_retries par cluster.
Détection d’Outliers : Éjecte automatiquement les hôtes non sains du pool d’équilibrage. Après cinq réponses 5xx consécutives, l’endpoint est éjecté pendant 30 secondes. max_ejection_percent évite d’éjecter tous les hôtes lors d’une dégradation globale de l’upstream.
Injection de Pannes : Injecte de la latence ou des erreurs dans un pourcentage de requêtes pour les tests de chaos, configurable par route sans changements dans le code de l’application.
Autorisation Externe : Délègue les décisions d’autorisation à un service gRPC externe (OPA, Ory Keto). Le filtre ext_authz envoie les en-têtes de requête au service d’autorisation avant de transmettre en amont.
Extensions Wasm : Envoy prend en charge les plugins de filtres WebAssembly pour la logique métier personnalisée dans tout langage compilant vers Wasm (Go, Rust, C++). Les filtres Wasm sont rechargés à chaud sans mises à jour binaires.
Envoy vs Autres Proxies
| Fonctionnalité | Envoy | Nginx | HAProxy | Traefik | Linkerd | MOSN |
|---|---|---|---|---|---|---|
| Config dynamique | xDS API (sans rechargement) | nginx -s reload | API temps réel | Auto-découverte K8s | xDS (limité) | xDS API |
| Service mesh | Oui (Istio, Consul) | Non | Non | Non (ingress seul) | Oui (Linkerd2) | Oui |
| Protocoles L7 | HTTP/1.1, HTTP/2, gRPC, Thrift | HTTP/1.1, HTTP/2 | HTTP/1.1, HTTP/2 | HTTP/1.1, HTTP/2 | HTTP/1.1, HTTP/2, gRPC | HTTP/1.1, HTTP/2, Dubbo |
| Observabilité | Stats + traçage intégrés | Basé sur modules | Socket de stats | Plugin Prometheus | Signaux dorés intégrés | Stats intégrés |
| mTLS | SDS + SPIFFE | Certs manuels | Certs manuels | Certs manuels | Automatique | SDS |
| Filtres Wasm | Oui | Non | Non | Non | Non | Oui |
Exemple Pratique : Envoy comme Proxy Frontal
Vous avez trois microservices (users, orders, products) derrière Envoy comme edge proxy, avec le trafic partagé entre v1 et v2 du service de commandes pour un déploiement canary :
routes:
- match:
prefix: "/orders"
route:
weighted_clusters:
clusters:
- name: orders_v1
weight: 90
- name: orders_v2
weight: 10
total_weight: 100
Cette configuration de cluster pondéré envoie 10% du trafic /orders vers le canary v2 sans aucun changement dans le code de l’application.
Pièges et Cas Limites
- Sensibilité à la casse des en-têtes : Les en-têtes HTTP/2 sont en minuscules par défaut. Envoy les normalise — assurez-vous que vos services gèrent
content-type,authorizationen minuscules. - Timeouts upstream vs de route :
connect_timeoutdu cluster (TCP) ettimeoutde la route (requête) sont indépendants. Le timeout de route par défaut est 15 secondes — définissez-le explicitement. - Budget de nouvelles tentatives : Sans limites sur
retry_on, les nouvelles tentatives sous charge peuvent amplifier les défaillances. Combinez toujours les nouvelles tentatives avec un circuit breaker.
Dépannage
| Symptôme | Cause Probable | Solution |
|---|---|---|
503 upstream_reset_before_response_started | L’upstream a fermé la connexion avant de répondre | Vérifiez le chemin du health check ; augmentez connect_timeout |
| 404 d’Envoy (pas de l’upstream) | Aucune route correspondante | Exécutez /config_dump sur le port admin ; vérifiez le domaine du virtual host |
| Circuit breaker ouvert dans les stats | Upstream surchargé | Augmentez max_pending_requests ou mettez à l’échelle l’upstream |
| Échec de handshake mTLS | Discordance SAN du certificat | Vérifiez que match_subject_alt_names correspond à l’URI SPIFFE réel |
| Latence P99 élevée | Famine de threads | Augmentez le nombre de threads worker avec concurrency dans le bootstrap |
Résumé
- L’API xDS permet une configuration entièrement dynamique sans redémarrage — clusters, routes, listeners et certificats se mettent à jour en direct.
- L’équilibrage de charge offre six algorithmes dont Ring Hash pour l’affinité de cache et Least Request pour les charges de travail hétérogènes.
- L’observabilité intégrée fournit des stats Prometheus, des en-têtes de traçage distribué et des journaux d’accès JSON structurés.
- mTLS via SDS + SPIFFE délivre des réseaux zero-trust avec des certificats de courte durée renouvelés automatiquement.
- Les filtres avancés rendent Envoy extensible sans toucher au code de l’application.