Le problème du LoadBalancer en bare-metal
Dans les environnements cloud (AWS, GCP, Azure), les services Kubernetes de type LoadBalancer provisionnent automatiquement un load-balancer cloud avec une IP publique. En bare-metal ou en datacenter privé, ce mécanisme n’existe pas nativement dans OpenShift.
MetalLB résout ce problème en implémentant un contrôleur de LoadBalancer pour les clusters bare-metal. Il attribue des adresses IP aux services LoadBalancer depuis des plages configurées et les annonce sur le réseau via deux modes : Layer 2 (ARP/NDP) ou BGP.
Installation via l’Operator MetalLB
Red Hat maintient un Operator MetalLB certifié pour OpenShift, disponible dans l’OperatorHub.
# Créer le namespace MetalLB
oc create namespace metallb-system
# Installer l'Operator
cat <<EOF | oc apply -f -
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: metallb-operator
namespace: metallb-system
spec:
channel: stable
name: metallb-operator
source: redhat-operators
sourceNamespace: openshift-marketplace
EOF
Ensuite, instancier MetalLB en créant la CR MetalLB :
apiVersion: metallb.io/v1beta1
kind: MetalLB
metadata:
name: metallb
namespace: metallb-system
spec:
nodeSelector:
node-role.kubernetes.io/worker: ""
Mode Layer 2 (L2)
Le mode L2 est le plus simple à mettre en place. MetalLB désigne un nœud speaker qui répond aux requêtes ARP (IPv4) ou NDP (IPv6) pour les IPs des services LoadBalancer. Tout le trafic passe par ce nœud avant d’être distribué via kube-proxy.
Quand utiliser L2 ?
- Réseau plat (même sous-réseau L2 entre les nœuds et les clients)
- Environnements de lab ou petits clusters
- Pas de routeurs BGP disponibles
- Bande passante suffisante sur un seul nœud
Configuration L2
# Définir un pool d'adresses IP
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: pool-l2
namespace: metallb-system
spec:
addresses:
- 192.168.1.200-192.168.1.250
autoAssign: true
---
# Activer l'annonce L2 pour ce pool
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: annonce-l2
namespace: metallb-system
spec:
ipAddressPools:
- pool-l2
# Optionnel : restreindre à certains nœuds
nodeSelectors:
- matchLabels:
kubernetes.io/os: linux
Limitation du mode L2
L’inconvénient majeur est l’absence de distribution de charge réelle : tout le trafic entrant transite par un seul nœud (le speaker actif). En cas de panne, MetalLB bascule automatiquement sur un autre nœud (failover ~10 secondes).
Mode BGP
Le mode BGP (Border Gateway Protocol) est recommandé pour les environnements de production. MetalLB établit des sessions BGP avec les routeurs d’infrastructure et annonce les routes vers les IPs des services LoadBalancer. Le trafic est ainsi distribué directement vers les nœuds par le routeur, offrant une vraie distribution de charge (ECMP).
Prérequis
- Un ou plusieurs routeurs supportant BGP (Cisco, Juniper, FRRouting, etc.)
- Des ASN (Autonomous System Numbers) alloués pour MetalLB et les routeurs pairs
- Connectivité réseau entre les nœuds MetalLB speakers et les routeurs
Architecture BGP typique
Internet / LAN
│
Routeur (ASN 65000)
├── Peer: node-1 (ASN 65001) → IP 10.0.0.1/32
├── Peer: node-2 (ASN 65001) → IP 10.0.0.1/32
└── Peer: node-3 (ASN 65001) → IP 10.0.0.1/32
Chaque nœud annonce la même IP → le routeur distribue via ECMP.
Configuration BGP
# Pool d'adresses pour BGP
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: pool-bgp
namespace: metallb-system
spec:
addresses:
- 10.0.0.0/24
autoAssign: true
---
# Définir les pairs BGP (routeurs)
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
name: routeur-core
namespace: metallb-system
spec:
myASN: 65001 # ASN de MetalLB
peerASN: 65000 # ASN du routeur
peerAddress: 172.16.0.1
# Optionnel : restreindre à des nœuds spécifiques
nodeSelectors:
- matchLabels:
node-role.kubernetes.io/worker: ""
---
# Activer l'annonce BGP pour le pool
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
name: annonce-bgp
namespace: metallb-system
spec:
ipAddressPools:
- pool-bgp
aggregationLength: 32 # Annonce des /32 par IP
communities:
- 65000:100 # Communauté BGP custom
BGP avec BFD (Bidirectional Forwarding Detection)
BFD permet une détection rapide des pannes de liaison (sub-seconde) :
apiVersion: metallb.io/v1beta1
kind: BFDProfile
metadata:
name: bfd-fast
namespace: metallb-system
spec:
receiveInterval: 150 # ms
transmitInterval: 150 # ms
detectMultiplier: 3
echoMode: false
---
# Référencer le profil BFD dans le BGPPeer
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
name: routeur-core-bfd
namespace: metallb-system
spec:
myASN: 65001
peerASN: 65000
peerAddress: 172.16.0.1
bfdProfile: bfd-fast
Utiliser un service LoadBalancer
Une fois MetalLB configuré, la création d’un service LoadBalancer est standard :
apiVersion: v1
kind: Service
metadata:
name: mon-service
namespace: production
annotations:
# Forcer l'utilisation d'un pool spécifique
metallb.universe.tf/address-pool: pool-bgp
spec:
type: LoadBalancer
selector:
app: mon-app
ports:
- port: 443
targetPort: 8443
protocol: TCP
Vérifier l’IP attribuée :
oc get svc mon-service -n production
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
# mon-service LoadBalancer 10.96.45.12 10.0.0.5 443:30042/TCP
Permissions SELinux et SCC sur OpenShift
OpenShift impose des Security Context Constraints (SCC) strictes. Les pods MetalLB speaker ont besoin de capacités réseau spéciales. L’Operator gère automatiquement les SCC nécessaires, mais vérifier :
# Vérifier les SCC appliquées aux speakers
oc get pod -n metallb-system -l component=speaker \
-o jsonpath='{.items[*].metadata.annotations.openshift\.io/scc}'
Les speakers ont besoin de privileged ou d’une SCC custom permettant NET_RAW et NET_ADMIN.
Comparaison L2 vs BGP
| Critère | Mode L2 | Mode BGP |
|---|---|---|
| Simplicité | Très simple | Configuration réseau requise |
| Distribution de charge | Non (nœud unique) | Oui (ECMP) |
| Failover | ~10 secondes | Sub-seconde avec BFD |
| Scalabilité | Limitée | Haute |
| Prérequis réseau | Aucun | Routeurs BGP |
| Cas d’usage | Lab, dev, petits clusters | Production, bare-metal entreprise |
Conclusion
MetalLB comble un manque critique pour les déploiements OpenShift bare-metal. En mode L2, il est opérationnel en quelques minutes. En mode BGP, il offre une solution de production robuste avec distribution de charge réelle et failover rapide, à condition d’avoir l’infrastructure réseau adaptée.