MetalLB et le réseau


Sur le cloud, quand tu crées un Service de type LoadBalancer, AWS/GCP te file automatiquement une IP publique. Sur bare metal, c’est… rien. L’IP reste en “pending” indéfiniment.

C’est là qu’intervient MetalLB.

Le problème

apiVersion: v1
kind: Service
metadata:
  name: mon-app
spec:
  type: LoadBalancer
  ports:
    - port: 80
kubectl get svc mon-app
# NAME      TYPE           EXTERNAL-IP   PORT(S)
# mon-app   LoadBalancer   <pending>     80:31234/TCP

Kubernetes attend qu’un cloud provider lui attribue une IP. Sauf qu’on est sur du bare metal, y’a pas de cloud provider.

MetalLB à la rescousse

MetalLB c’est un LoadBalancer pour bare metal. Tu lui donnes une plage d’IPs de ton réseau local, et il les attribue aux services.

Installation

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.3/config/manifests/metallb-native.yaml

Configuration

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default-pool
  namespace: metallb-system
spec:
  addresses:
    - 192.168.1.200-192.168.1.220

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

J’ai réservé les IPs 200 à 220 pour MetalLB. Faut s’assurer que ton DHCP n’utilise pas cette plage.

Comment ça marche

En mode L2 (le plus simple), MetalLB répond aux requêtes ARP pour les IPs qu’il gère.

Quand quelqu’un sur le réseau demande “qui a 192.168.1.200?”, MetalLB répond “c’est moi!”. Le trafic arrive sur le node Kubernetes, et kube-proxy le route vers le bon pod.

Le test magique

kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --type=LoadBalancer --port=80
kubectl get svc nginx
NAME    TYPE           EXTERNAL-IP      PORT(S)
nginx   LoadBalancer   192.168.1.200    80:31234/TCP

Une vraie IP ! Et si tu fais curl http://192.168.1.200, t’as la page nginx.

Les pièges

1. Conflit d’IP

Si l’IP est déjà utilisée par un autre appareil sur le réseau, ça marche pas. MetalLB détecte pas les conflits.

Solution : Vérifier avec arp -a que les IPs sont libres.

2. Firewall du routeur

Certains routeurs bloquent le trafic entre appareils du même réseau (isolation client). Faut désactiver ça.

3. IPs fixes pour services critiques

Par défaut, MetalLB attribue les IPs dans l’ordre. Si tu veux une IP fixe pour un service :

apiVersion: v1
kind: Service
metadata:
  name: npm
  annotations:
    metallb.universe.tf/loadBalancerIPs: "192.168.1.202"
spec:
  type: LoadBalancer
  loadBalancerIP: 192.168.1.202

Mon allocation

IPService
192.168.1.200Traefik (Ingress)
192.168.1.201Console Web
192.168.1.202Nginx Proxy Manager
192.168.1.203+Apps déployées

Exposer vers Internet

MetalLB donne des IPs locales. Pour accéder depuis Internet, j’ai configuré du port forwarding sur mon routeur :

Port 80  → 192.168.1.202:80
Port 443 → 192.168.1.202:443

Le 192.168.1.202 c’est Nginx Proxy Manager, qui gère ensuite le routage vers les différents services.


Prochain article : Nginx Proxy Manager - HTTPS facile avec Let’s Encrypt.