Un Service Kubernetes de type LoadBalancer fonctionne sans réflexion sur EKS, GKE ou AKS : le fournisseur cloud provisionne une adresse IP externe et la route vers le cluster. Sur un cluster on-premise, ce même Service reste en Pending indéfiniment, EXTERNAL-IP jamais renseigné, parce qu’il n’existe aucun cloud provider pour répondre à la demande. C’est le piège le plus concret et le moins anticipé d’une migration depuis de l’infrastructure legacy : le YAML est identique, le comportement ne l’est pas.

Ce que MetalLB fait à la place d’un cloud provider

MetalLB implémente lui-même ce que le cloud fait ailleurs : il surveille les Services LoadBalancer non satisfaits, leur assigne une IP depuis une plage que vous définissez, et annonce cette IP au réseau environnant pour qu’elle devienne réellement routable.

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: production-pool
  namespace: metallb-system
spec:
  addresses:
    - 192.168.10.100-192.168.10.150

Cette plage doit être réservée nulle part ailleurs sur le réseau (aucun DHCP, aucun autre équipement ne doit pouvoir attribuer ces mêmes adresses) : MetalLB ne négocie pas leur possession, il part du principe qu’elles lui sont acquises.

Deux modes d’annonce, deux compromis réseau

MetalLB propose deux façons d’annoncer une IP au reste du réseau, avec des implications d’infrastructure différentes.

Le mode Layer 2 fait répondre un seul nœud aux requêtes ARP pour l’IP attribuée : simple à mettre en place, sans configuration réseau particulière, mais tout le trafic pour cette IP transite par un seul nœud à la fois, un point de contention qui devient un goulot d’étranglement au-delà d’un trafic modeste. Le composant speaker responsable de cette annonce tourne d’ailleurs en DaemonSet, présent sur chaque nœud éligible pour pouvoir répondre où que l’élection le désigne.

apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: l2-production
  namespace: metallb-system
spec:
  ipAddressPools:
    - production-pool

Le mode BGP annonce chaque IP via le protocole BGP à un ou plusieurs routeurs, qui répartissent alors réellement le trafic entre plusieurs nœuds. Le bénéfice (une vraie répartition de charge, une bascule plus rapide en cas de panne d’un nœud) a un coût réel : il exige un routeur qui parle BGP et une équipe réseau qui accepte de le configurer, une dépendance que le mode Layer 2 évite entièrement.

Le choix qui décide tout : Layer 2 d’abord, BGP si le trafic l’impose

Démarrer en Layer 2 est le choix par défaut raisonnable pour la plupart des migrations : il fonctionne sans toucher à l’infrastructure réseau existante, ce qui compte quand l’équipe réseau et l’équipe plateforme ne sont pas encore rodées à travailler ensemble. Passer en BGP se justifie seulement quand le trafic réel dépasse ce qu’un nœud unique absorbe confortablement, jamais par anticipation d’un trafic qui n’existe pas encore.

Ce que MetalLB ne résout pas

MetalLB donne une IP externe routable à un Service, rien de plus : il ne gère ni certificat TLS, ni règles de routage HTTP par nom d’hôte, ni équilibrage applicatif fin. Ces responsabilités restent celles d’un Ingress placé devant, qui utilise justement un Service LoadBalancer MetalLB comme point d’entrée réseau. Les deux se combinent sans conflit : MetalLB résout la couche réseau, l’Ingress résout la couche applicative.

À retenir

Un Service LoadBalancer qui reste en Pending sur un cluster on-premise n’est pas un bug : c’est l’absence attendue d’un cloud provider, que MetalLB comble explicitement. Le mode Layer 2 couvre la grande majorité des migrations sans toucher au réseau existant ; le mode BGP ne se justifie que sous une charge réelle qui le demande. Poser ce socle réseau correctement fait partie de ce qui se joue dès les premières étapes d’une migration Kubernetes depuis une infrastructure legacy.