Skip to content

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-start avec 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'EnvoyProxy n'est que de la configuration, il n'ajoute aucune ressource AWS à nettoyer.
  • ExternalDNS : le CNAME api.devopsyouss.com suit 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