Kubernetes : loadbalancer
Bonjour,
Aujourd'hui, un billet portant sur le passage du mode NodePort avec un seul node master a un mode LoadBalancer avec deux nodes master.
Contexte : cluster avec 2 nodes ( un master Ubuntu 22 et un Flatcar) et 3 nodes workers.
Actuellement, j'utilise ingress-nginx en mode NodePort pour accéder aux différents services. Cela amène une coupure si le node en question (le master) est coupé ou reboot pour upgrade.
L'objectif est de passer sur un mode LoadBalancer de type L2 via MetalLB pour pouvoir s'affranchir de cette problématique.
Très bonne vidéo à ce sujet :
https://www.youtube.com/watch?v=k8bxtsWe9qw
Installation de MetalLB via helm :
helm repo add metallb https://metallb.github.io/metallb
kubectl create ns metallb-system
helm install metallb metallb/metallb --namespace metallb-system
En l'état, metallb reste en idle car il faut le configurer.
Mais avant, il faut modifier l'ingress-nginx pour passer de nodeport à loadbalancer (ce qui amène une coupure de l'accès aux services le temps de finir la configuration) :
kubectl edit service ingress-nginx-controller -n ingress-nginx
Retirer externalIP et modifier spec.type de NodePort à LoadBalancer :
apiVersion: v1
kind: Service
metadata:
annotations:
meta.helm.sh/release-name: ingress-nginx
meta.helm.sh/release-namespace: ingress-nginx
metallb.universe.tf/ip-allocated-from-pool: vip-ingress-nginx
creationTimestamp: "2024-07-12T08:16:21Z"
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.11.0
helm.sh/chart: ingress-nginx-4.11.0
name: ingress-nginx-controller
namespace: ingress-nginx
resourceVersion: "51393888"
uid: df9d612c-de4d-4010-a6ae-1c749b12b8fd
spec:
allocateLoadBalancerNodePorts: true
clusterIP: 10.105.228.153
clusterIPs:
- 10.105.228.153
externalTrafficPolicy: Cluster
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- appProtocol: http
name: http
nodePort: 30158
port: 80
protocol: TCP
targetPort: http
- appProtocol: https
name: https
nodePort: 30899
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer: {}
On vérifie ensuite son état :
kubectl get svc -n ingress-nginx
ingress-nginx ingress-nginx-controller LoadBalancer 10.105.228.153 <pending> 80:30158/TCP,443:30899/TCP 99m
ingress-nginx ingress-nginx-controller-admission ClusterIP 10.100.199.101 <none> 443/TCP 99m
Il est en pending, c'est normal car il n'y a pas encore de service LoadBalancer de configuré.
Pour configurer MetalLB, il faut créer deux fichiers de configuration :
- pool.yaml : contient le/les pools d'adresses IP (qui peut être une unique ip en /32)
- l2advertisement.yaml : spécifie le/les pools d'adresses IP à utiliser
pool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: vip-ingress-nginx
namespace: metallb-system
spec:
addresses:
- 192.168.0.26/32
l2advertisement.yaml
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: l2-vip-ingress-nginx
namespace: metallb-system
spec:
ipAddressPools:
- vip-ingress-nginx
Application des fichiers de conf :
kubectl apply -f pool.yaml
kubectl apply -f l2advertisement.yaml
On vérifie que tout est bon côté conf :
kubectl get IPAddressPool -A
NAMESPACE NAME AUTO ASSIGN AVOID BUGGY IPS ADDRESSES
metallb-system vip-ingress-nginx true false ["192.168.0.26/32"]
kubectl get L2Advertisement -A
NAMESPACE NAME IPADDRESSPOOLS IPADDRESSPOOL SELECTORS INTERFACES
metallb-system l2-vip-ingress-nginx ["vip-ingress-nginx"]
Si tout est bon, on vérifie le service nginx :
kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.105.228.153 192.168.0.26 80:30158/TCP,443:30899/TCP 105m
ingress-nginx-controller-admission ClusterIP 10.100.199.101 <none> 443/TCP 105m
On voit que le service en mode LoadBalancer utilise bien l'adresse IP du pool que l'on a défini précédemment.
Dans ce mode L2 il y aura quand même une légère interruption de service lors d'une bascule, le temps que le nouveau "master" MetalLB soit promu.
Have fun.