Sur un Kubernetes hébergé chez un fournisseur cloud, demander un service de type LoadBalancer déclenche la création d'un équilibreur et l'attribution d'une adresse publique. Sur un cluster installé sur vos propres machines, la même demande reste indéfiniment en état <pending> : personne n'est là pour fournir l'adresse. MetalLB est ce quelqu'un.
Ce qu'il fait, précisément
MetalLB remplit deux fonctions :
- attribuer une adresse IP prise dans une plage que vous lui confiez, à chaque service qui en demande une ;
- annoncer cette adresse sur le réseau, pour que le trafic qui lui est destiné arrive effectivement sur un nœud du cluster.
Il se compose d'un controller, qui distribue les adresses, et d'un speaker présent sur chaque nœud, qui se charge de l'annonce.
Le mode Layer 2 : l'adresse qui se déplace

Un nœud répond aux requêtes ARP pour l'adresse du service ; si ce nœud tombe, un autre reprend l'annonce.
En mode Layer 2 — le plus simple, celui du lab — un seul nœud à la fois répond aux requêtes ARP concernant l'adresse, exactement comme s'il la portait sur son interface. Tout le trafic destiné à cette adresse arrive donc chez lui, puis est distribué à l'intérieur du cluster vers les pods concernés, où qu'ils soient.
Si ce nœud disparaît, un autre speaker prend le relais et réémet l'annonce : l'adresse réapparaît en quelques secondes, sans intervention.
Ce que ce n'est pas : de la répartition de charge. À un instant donné, un seul nœud reçoit le trafic entrant. C'est de la haute disponibilité d'adresse, ce qui est déjà beaucoup, et amplement suffisant pour un lab ou une petite infrastructure.
Le mode BGP, en deux phrases
Si votre réseau dispose d'un routeur parlant BGP, MetalLB peut lui annoncer les adresses de service par ce protocole. Le routeur répartit alors réellement les flux entre les nœuds, et la bascule ne dépend plus de l'ARP. C'est le mode à privilégier en production sur un réseau maîtrisé — au prix d'un dialogue avec l'équipe réseau.
La configuration, en deux objets
apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: pool-labk3s namespace: metallb-system spec: addresses: - 192.168.50.230-192.168.50.250 --- apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: l2-labk3s namespace: metallb-system spec: ipAddressPools: - pool-labk3s
Le premier objet déclare la réserve d'adresses, le second indique comment les annoncer. C'est tout.
Les trois pièges
- La plage doit être hors du pool DHCP. Sinon, un jour, un poste recevra par DHCP une adresse déjà annoncée par MetalLB — et le symptôme (un service qui répond une fois sur deux) est particulièrement pénible à diagnostiquer. Réserver le haut de la plage aux services est une bonne habitude.
- Désactiver l'équilibreur intégré de K3S. K3S embarque « Klipper » (servicelb), qui remplit un rôle voisin et entre en conflit. On le désactive dans
/etc/rancher/k3s/config.yamlavecdisable: - servicelb, sur tous les nœuds. - Le réseau doit accepter le déplacement d'adresse. Sur un réseau physique avec sécurité de port ou filtrage ARP strict, l'annonce Layer 2 peut être bloquée. Sur un réseau virtuel libvirt, aucun problème.
Une adresse ou plusieurs ?
Rien n'empêche de donner une adresse à chaque service, mais l'usage recommandé est l'inverse : une seule adresse pour l'Ingress Controller, et tous les services HTTP exposés derrière lui par nom de domaine. Les adresses supplémentaires se réservent aux services non HTTP — une base de données, un serveur de jeu, du SMTP — qu'un Ingress ne sait pas router.
Voir la mise en pratique
Cette brique est installée et configurée pas à pas dans mon wiki, section Datacenter / Cluster K3S — la documentation de référence, avec les commandes et leurs sorties :
Et côté blog, l'étape correspondante du lab : Monter un lab Kubernetes chez soi (6) : MetalLB et Traefik, exposer les services.