ADR 017 — Load balancer d'exposition : NLB plutôt que Classic ELB (2026-06-14)
Statut
Accepté (2026-06-14). Issue #70. Validé live le 2026-06-16 (console AWS : 1 seul load balancer, de type Network, internet-facing, aucun Classic ELB).
Contexte
Le Service LoadBalancer provisionné par Envoy Gateway pour le Gateway
(point d'entrée public, ADR 010) crée par défaut un Classic ELB (CLB) sur AWS.
Le CLB est déprécié par AWS : plus de nouvelles fonctionnalités, pas de
preserve client IP natif, pas de mode IP target, latence supérieure à un NLB.
Décision 1 — NLB plutôt que CLB
On provisionne un Network Load Balancer (NLB, L4) à la place du CLB, via une
ressource EnvoyProxy (gateway.envoyproxy.io/v1alpha1) qui annote le Service
Envoy et est référencée par le GatewayClass (parametersRef) :
spec:
provider:
kubernetes:
envoyService:
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
Le GatewayClass ne se personnalise pas directement : Envoy Gateway délègue la
config d'infrastructure à un EnvoyProxy (cluster-level via parametersRef),
qui doit vivre dans le namespace du contrôleur (envoy-gateway-system).
Décision 2 — NLB, pas ALB
L'ALB (L7) serait redondant avec Envoy Gateway, qui fait déjà tout le routing L7 (HTTPRoute, terminaison TLS via cert-manager, hostnames). Un ALB en amont ajouterait une couche L7 inutile et du lock-in AWS. Le NLB (L4, TCP pass-through) est la bonne brique : il transporte le trafic jusqu'à Envoy, qui gère le L7 en aval. Cohérent avec ADR 010 (exposition portable, pas de dépendance à un Ingress controller AWS).
Décision 3 — Annotation in-tree, pas AWS Load Balancer Controller
Deux façons d'obtenir un NLB :
| Voie | Annotation | Prérequis |
|---|---|---|
| In-tree (retenue) | aws-load-balancer-type: "nlb" |
Aucun (cloud provider AWS intégré) |
| AWS LB Controller | aws-load-balancer-type: "external" + nlb-target-type: "ip" |
Installer l'AWS LB Controller |
On retient l'in-tree : le projet n'installe pas l'AWS Load Balancer
Controller (Envoy assure le L7, on ne veut pas d'un second contrôleur LB). Le
NLB en mode instance couvre le besoin. Tradeoff assumé : pas de mode IP target
(qui éviterait le double saut via NodePort). Migration possible vers l'AWS LB
Controller + target-type: ip si le besoin de preserve client IP / IP target
apparaît (évolution).
Pièges / Conséquences
- Cluster éphémère = pas de migration in-place : le NLB est créé from-scratch
à chaque
aws-startavec le Gateway. On évite le piège du changement de type d'ELB sur un Service existant (AWS recrée le LB, l'ancien peut rester orphelin). L'ancien CLB n'existe que le temps d'une session ; sur un cluster neuf, seul le NLB est créé. - Teardown inchangé (anti-INC-016) : le NLB est supprimé quand le Gateway est
supprimé (Envoy Gateway supprime son Service), exactement comme le CLB
aujourd'hui. L'
EnvoyProxyn'est que de la configuration, il n'ajoute aucune ressource AWS à nettoyer. - ExternalDNS : le CNAME
api.devopsyouss.comsuit le hostname du nouveau LB automatiquement (source gateway-httproute), aucune action manuelle.
Validation
- Hors infra : YAML conforme à l'API Envoy Gateway (EnvoyProxy + parametersRef).
- Live (2026-06-16, critères de l'issue #70) : console AWS = 1 NLB de type
Network (pas de CLB),
curl https://api.devopsyouss.com/healthz/ready→ 200, aucun CLB orphelin. ✅
Date : 2026-06-14 Sprint : 4 Issue : #70