Préparation à la CKA - 10 - Services - LoadBalancer

Publié le 15/10/2024 par Ali Sanhaji

Services

Dans les deux derniers articles sur les Services, nous avons vu les deux types ClusterIP et NodePort. Le premier sert surtout quand on a des applications à l’intérieur du cluster qui veulent s’appeler les unes les autres. Le second sert pour exposer à l’extérieur du cluster une application, en utilisant les IPs des nœuds du cluster. Mais ces IPs ne sont souvent pas publiques, et ne servent que pour faire des tests ou pour exposer des applications en interne.

Dans le cas où nous avons une application qu’on doit exposer sur internet, par exemple un site marchand d’une entreprise de la grande distribution, il nous faut un autre type de Service. Nous allons donc voir le type LoadBalancer.

LoadBalancer

Le Service de type LoadBalancer permet, comme son nom l’indique, de demander la création d’un load balancer en tant que point d’entrée de notre service vers nos pods en backend. Vous allez me dire, mais où est-ce qu’est créé ce load balancer ? Eh ben, ça dépend de là où est déployé votre cluster kubernetes. Si votre cluster Kubernetes est sur un cloud provider comme Azure ou GCP (par exemple si vous utilisez AKS ou GKE), c’est le cloud provider qui vous fournit le load balancer. Lorsque vous créez un Service de type Load Balancer, il y a un contrôleur dans votre cluster qui surveille ce type d’objets, et qui traduit cette demande pour créer un load balancer sur Azure ou sur GCP en le configurant comme il faut afin qu’il renvoie le trafic vers les noeuds du cluster, qui vont ensuite renvoyés vers les pods en backend du Service.

Par défaut, les load balancers Azure ou GCP viennent avec une adresse IP publique qui sert de point d’entrée vers le Service. Ainsi vous pouvez exposer votre application sur internet en utilisant ce load balancer.

Il est aussi possible de demander un load balancer avec une IP privée, pour exposer votre application sur le réseau interne plutôt. Ce qui permet de faire la même chose qu’avec des NodePort, mais sans avoir recours aux IPs des nœuds qui peuvent changer, alors que celle du LoadBalancer ne devrait pas changer.

Dans le cas où nous ne sommes pas sur un cloud provider, mais quand on a un déploiement sur bare metal par exemple, il faut trouver un autre moyen de créer des load balancers. Des solutions existent comme Metallb , ou OpenELB plus récemment.

Voyons un exemple de création de Service de type Load Balancer. Dans notre cluster que nous avons créé au début de cette série (lien vers le premier article), comme nous sommes sur des VMs en local sur notre ordinateur, nous devons utiliser une solution comme MetalLB pour créer des load balancers.

Voici le guide pour l’installer chez vous : Installaton metallb

Exemple Créons un déploiement d’un serveur web Apache avec deux replicas comme nous avons fait dans l’article précédent :

kubectl create deployment apache-loadbalancer --image=bitnami/apache:latest --replicas=2
deployment.apps/apache-loadbalancer created

Les pods sont bien déployés :

kubectl get pods
NAME                                   READY   STATUS    RESTARTS   AGE
apache-loadbalancer-6796d9f6cc-kr58r   1/1     Running   0          8s
apache-loadbalancer-6796d9f6cc-rjzxh   1/1     Running   0          8s

Pour exposer le déploiement, nous allons utiliser le service de type LoadBalancer :

kubectl expose deployment apache-loadbalancer --port=8080 --target-port=8080 --type=LoadBalancer
service/apache-loadbalancer exposed

Le service a bien été créé :

kubectl get svc
NAME                  TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE
apache-loadbalancer   LoadBalancer   10.101.178.57   172.16.1.101   8080:31575/TCP   4s

L’adresse IP externe qui a été attribuée est bien dans le pool que nous avons spécifié à MetalLB, et qui est bien routable pour nous. Sur un cloud provider comme Azure ou GCP, cette adresse IP aurait été une adresse IP publique fournie par le cloud provider.

Si nous regardons la configuration du Service, on voit bien que dans notre cas, MetalLB s’est chargé de fournir le load balancer avec une adresse IP.

kubectl describe service apache-loadbalancer
Name:                     apache-loadbalancer
Namespace:                default
Labels:                   app=apache-loadbalancer
Annotations:              <none>
Selector:                 app=apache-loadbalancer
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.101.178.57
IPs:                      10.101.178.57
LoadBalancer Ingress:     172.16.1.101
Port:                     <unset>  8080/TCP
TargetPort:               8080/TCP
NodePort:                 <unset>  31575/TCP
Endpoints:                10.244.1.40:8080,10.244.2.39:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason        Age   From                Message
  ----    ------        ----  ----                -------
  Normal  IPAllocated   28s   metallb-controller  Assigned IP ["172.16.1.101"]
  Normal  nodeAssigned  28s   metallb-speaker     announcing from node "k8s-node-1" with protocol "layer2"

Les IPs en endpoints sont bien celles des pods que nous avons créés.

kubectl get pods -o wide
NAME                                   READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE
apache-loadbalancer-6796d9f6cc-kr58r   1/1     Running   0          68s   10.244.2.39   k8s-node-2
apache-loadbalancer-6796d9f6cc-rjzxh   1/1     Running   0          68s   10.244.1.40   k8s-node-1

Il suffit enfin, pour accéder à nos serveurs web Apache, de faire une requête sur l’adresse IP du load balancer avec le port 8080 qui a été configuré.

curl http://172.16.1.101:8080
<html><body><h1>It works!</h1></body></html>

Conclusion

Nous avons vu jusqu’ici les trois types majeurs de Service. Le type Load Balancer sert ici pour exposer des applications à l’extérieur de notre cluster avec des adresses IPs externes. Nous allons voir que ce n’est pas la seule façon d’exposer les applications à l’extérieur, mais qu’il y a encore une manière plus spécifique au trafic de type HTTP/HTTPS.

Dans le prochain article, nous allons donc parler des objets Ingress.