Tableau de bord Traefik du cluster
Infrastructure

Monter un lab Kubernetes chez soi (6) : MetalLB et Traefik, exposer les services

Un service LoadBalancer qui reste en attente, une adresse IP qui n'existe nulle part : comment MetalLB, Traefik et une seule ligne de DNS wildcard règlent la question de l'accès aux applications.

Le cluster tourne, le stockage est répliqué. Reste la question qui bloque tous les Kubernetes auto-hébergés : comment un utilisateur atteint-il une application ? Chez un fournisseur cloud, demander un service de type LoadBalancer déclenche la création d'un équilibreur de charge et l'attribution d'une adresse publique. Sur une machine dans un salon, il ne se passe rien du tout — le service reste indéfiniment en attente.

Deux briques, deux rôles distincts

  • MetalLB travaille au niveau réseau : il attribue une adresse IP au cluster et la fait exister sur le réseau local.
  • Traefik travaille au niveau HTTP : il reçoit tout le trafic arrivant sur cette adresse et le distribue selon le nom de domaine demandé.

Le premier donne une porte d'entrée, le second sait à quel appartement livrer. Les deux sont nécessaires.

MetalLB : une adresse IP qui appartient au cluster

K3S embarque un équilibreur simplifié — Klipper, ou servicelb — qui suffit à un nœud unique mais ne fournit pas d'adresse flottante. On le désactive proprement, sur les trois nœuds :

# /etc/rancher/k3s/config.yaml
disable:
  - servicelb
systemctl restart k3s

Puis on déploie MetalLB et on lui confie une plage d'adresses prise en dehors du pool DHCP — c'est le point à ne pas rater, sous peine de conflit d'adresses parfaitement invisible jusqu'au jour où il ne l'est plus :

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 mode Layer 2, en une phrase

Un des nœuds annonce l'adresse sur le réseau local — il répond aux requêtes ARP qui la concernent, comme s'il la portait. Tout le trafic destiné à cette adresse arrive donc sur ce nœud, qui le distribue ensuite dans le cluster. Si le nœud tombe, un autre reprend l'annonce en quelques secondes.

Ce n'est pas de la répartition de charge au sens strict — un seul nœud reçoit le trafic à un instant donné — mais c'est de la haute disponibilité : l'adresse survit à la perte d'une machine. Pour un lab comme pour beaucoup de petites infrastructures, c'est exactement ce qu'il faut. La répartition réelle demanderait du BGP, que MetalLB sait aussi faire.

Traefik : une adresse, tous les services

Traefik est déjà là : K3S l'installe par défaut comme contrôleur d'entrée. Il suffit de lui fixer l'adresse fournie par MetalLB, plutôt que de le laisser en prendre une au hasard dans la plage :

kubectl -n kube-system annotate svc traefik \
  metallb.universe.tf/loadBalancerIPs="192.168.50.250" --overwrite

Traefik fixé sur l'adresse du cluster, et un Ingress répondant par son nom

Une seule adresse IP en entrée, un routage par nom d'hôte en sortie : c'est tout le principe de l'Ingress.

Le wildcard DNS : la ligne qui change tout

Vient alors le geste le plus rentable de tout le lab. Dans la zone DNS de la passerelle, une seule ligne :

*.cluster    IN  A   192.168.50.250

Sans oublier d'incrémenter le numéro de série de la zone, puis :

named-checkzone labk3s.ev1 /etc/bind/zones/db.labk3s.ev1
systemctl reload bind9

À partir de cet instant, tout nom en *.cluster.labk3s.ev1 — y compris ceux qui n'existent pas encore — pointe vers le cluster. Déployer une nouvelle application ne demandera plus jamais de toucher au DNS : c'est l'Ingress qui déclare le nom, et il fonctionne immédiatement.

Le test qui valide la chaîne

Un déploiement minimal, un service, un Ingress :

kubectl create deployment web --image=nginx
kubectl expose deployment web --port 80
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web
spec:
  rules:
  - host: nginx.cluster.labk3s.ev1
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80
curl -I http://nginx.cluster.labk3s.ev1
HTTP/1.1 200 OK
Server: nginx/1.29.4

Ce 200 OK valide d'un coup toute la chaîne : la résolution DNS wildcard, l'annonce de l'adresse par MetalLB, le routage par nom dans Traefik, et le service jusqu'au conteneur. Si quelque chose cloche, on peut d'ailleurs court-circuiter le DNS pour isoler la panne :

curl -I -H "Host: nginx.cluster.labk3s.ev1" http://192.168.50.250

Une réponse correcte ici mais pas avec le nom : le problème est dans le DNS. Une erreur dans les deux cas : il est dans le cluster.

Le tableau de bord de Traefik

Tableau de bord de Traefik : points d'entrée, routeurs et services

Le tableau de bord montre les points d'entrée, les routeurs déclarés et l'état des services — pratique pour comprendre pourquoi une route ne prend pas.

Traefik expose un tableau de bord qui liste les points d'entrée, les routeurs issus des Ingress et les services associés. En lab, il s'expose comme n'importe quelle autre application. En production, certainement pas : il révèle toute la topologie de routage et doit rester sur une interface réservée, derrière une authentification forte.

Ce qui est acquis à ce stade

Le cluster a une adresse d'entrée stable, résistante à la perte d'un nœud, et un domaine entier qui pointe dessus. Déployer une application se résume désormais à écrire un fichier YAML — c'est l'objet du dernier article.

Le pas à pas détaillé est sur le wiki

Cet article ne remplace pas la documentation : il en explique les choix. L'intégralité de la démarche — commandes, sorties d'écran, vérifications et captures — est publiée sur mon wiki, dans la section Datacenter / Cluster K3S. Pages correspondant à cet article :

La série « Lab Kubernetes maison »

Cet article fait partie d'une série qui monte, pas à pas, un cluster Kubernetes complet sur une seule machine physique :

  1. 1. L'architecture avant les commandes
  2. 2. KVM et libvirt, le socle de virtualisation
  3. 3. La passerelle : routage, NAT, DHCP et DNS
  4. 4. Le cluster K3S en haute disponibilité
  5. 5. Longhorn, le stockage distribué
  6. 6. MetalLB et Traefik : exposer les services — vous y êtes
  7. 7. Déployer une application et superviser
Retour au blog