Sur un cluster Kubernetes, disposer d'assez d'adresses IP pour les Services Kubernetes devient vite un enjeu critique pour scaler et maintenir votre infrastructure.
Les Services offrent un moyen abstrait d'exposer une application qui s'exécute sur un ensemble de Pods. Différents types de Services, comme ClusterIP, NodePort et LoadBalancer, utilisent une adresse IP virtuelle unique au sein du cluster, appelée ClusterIP.
Chaque adresse IP de cluster d'un Service doit être unique sur l'ensemble du cluster. Toute tentative de création d'un Service avec un ClusterIP déjà alloué se solde par une erreur. À mesure que votre déploiement grandit, la plage d'IP de Service par défaut peut devenir insuffisante et provoquer des goulets d'étranglement sur les ressources réseau.
Jusqu'à présent, il n'était pas possible de redimensionner ni d'étendre les plages d'IP attribuées aux Services, ce qui posait problème en cas de chevauchement de réseaux ou lorsque le cluster arrivait à court d'adresses IP disponibles.
Désormais, les kube-apiserver sur lesquels la feature gate MultiCIDRServiceAllocator et l'API networking.k8s.io/v1alpha1 sont activées permettent d'étendre dynamiquement le nombre d'IP disponibles pour les Services. Cette fonctionnalité passe en bêta dans Kubernetes 1.31 ; il est recommandé d'attendre son passage en stable avant de l'utiliser en production. Consultez la KEP-1880—Multiple Service CIDRs pour plus de détails sur l'implémentation.
Dans cet article, nous verrons comment étendre la plage d'IP de Service sur un cluster Google Kubernetes Engine (GKE). Vous pouvez également tester cette fonctionnalité sur d'autres distributions Kubernetes ; reportez-vous aux notes de version propres à chaque distribution pour les détails de configuration ou les éventuelles limitations.
Prérequis
Vous devez disposer d'un cluster GKE en version 1.31.1-gke.1361000 ou ultérieure, et veiller à ce que l'outil en ligne de commande kubectl soit configuré pour communiquer avec votre cluster.
Activer et vérifier les API bêta
Depuis Kubernetes 1.24, les nouvelles API bêta sont désactivées par défaut sur les nouveaux clusters GKE. Les clusters existants créés sur une version antérieure à 1.24 conservent leurs API bêta activées.
Vous pouvez activer les API bêta au moment de la création du cluster ou plus tard. Pour activer les API bêta requises, suivez les instructions de Use Kubernetes beta APIs with GKE clusters.
Exemple de commande pour activer les API bêta requises sur un cluster existant :
gcloud container clusters update <<GKE_CLUSTER_NAME>> \
--enable-kubernetes-unstable-apis=networking.k8s.io/v1beta1/ipaddresses,networking.k8s.io/v1beta1/servicecidrs
--region <<GKE_CLUSTER_REGION>> \
--project <<GCP_PROJECT_NAME>>
Les API nouvellement activées créeront un objet ServiceCIDR portant le nom bien connu kubernetes, avec une plage d'adresses IP basée sur le CIDR de Service initial.
Exécutez la commande ci-dessous pour vérifier le nouvel objet ServiceCIDR :
Chimbus-MacBook-Pro:~ chimbu$ kubectl get servicecidr
NAME CIDRS AGE
kubernetes 10.96.0.0/28 98m
Chimbus-MacBook-Pro:~ chimbu$
Ajouter un nouveau ServiceCIDR
Pour les besoins du test, j'ai créé un cluster avec une plage /28 pour les services, soit seulement 14 adresses IP. Le Service kubernetes.default étant toujours créé, il ne reste donc que 13 Services possibles dans cet exemple.
Pour les besoins du test, j'ai créé un cluster avec une plage /28 pour les services, qui ne contient que 14 adresses IP. Le service kubernetes.default étant toujours créé, il ne reste que 13 Services possibles.
Essayez de créer des services Kubernetes supplémentaires : la requête échouera avec une erreur interne dès que toutes les adresses IP de la plage de service seront utilisées.
Chimbus-MacBook-Pro:~ chimbu$ for i in $(seq 1 13); do kubectl create service clusterip "service-test-$i" --tcp 80 -o json | jq -r .spec.clusterIP; done
10.96.0.13
10.96.0.11
10.96.0.7
10.96.0.14
10.96.0.3
10.96.0.12
10.96.0.9
10.96.0.4
10.96.0.5
error: failed to create ClusterIP service: Internal error occurred: failed to allocate a serviceIP: range is full
error: failed to create ClusterIP service: Internal error occurred: failed to allocate a serviceIP: range is full
error: failed to create ClusterIP service: Internal error occurred: failed to allocate a serviceIP: range is full
error: failed to create ClusterIP service: Internal error occurred: failed to allocate a serviceIP: range is full
Chimbus-MacBook-Pro:~ chimbu$
Vous pouvez maintenant augmenter le nombre d'adresses IP disponibles pour les Services en créant un nouveau ServiceCIDR qui prolonge la plage existante ou en ajoute de nouvelles.
Pendant la phase bêta, GKE n'autorise la création de Service CIDRs que dans la plage d'adresses IP réservée
34.118.224.0/20, afin d'éviter d'éventuels chevauchements de plages.
Appliquez le manifeste ci-dessous pour créer un nouveau ServiceCIDR qui ajoute une nouvelle plage d'adresses IP.
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1beta1
kind: ServiceCIDR
metadata:
name: newcidr1
spec:
cidrs:
- 34.118.224.0/20
EOF
Chimbus-MacBook-Pro:~ chimbu$ kubectl get servicecidrs.networking.k8s.io
NAME CIDRS AGE
kubernetes 10.96.0.0/28 104m
newcidr1 34.118.224.0/20 5s
Chimbus-MacBook-Pro:~ chimbu$
Essayez de créer de nouveaux services Kubernetes : leur adresse IP de cluster sera désormais prise dans cette nouvelle plage.
Chimbus-MacBook-Pro:~ chimbu$ for i in $(seq 1 13); do kubectl create service clusterip "service-test-new-$i" --tcp 80 -o json | jq -r .spec.clusterIP; done
34.118.235.89
34.118.234.162
34.118.230.252
34.118.226.209
34.118.227.183
34.118.227.182
^C
Chimbus-MacBook-Pro:~ chimbu$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 105m
service-test-1 ClusterIP 10.96.0.13 <none> 80/TCP 3m41s
service-test-2 ClusterIP 10.96.0.11 <none> 80/TCP 3m39s
service-test-3 ClusterIP 10.96.0.7 <none> 80/TCP 3m39s
service-test-4 ClusterIP 10.96.0.14 <none> 80/TCP 3m38s
service-test-5 ClusterIP 10.96.0.3 <none> 80/TCP 3m37s
service-test-6 ClusterIP 10.96.0.12 <none> 80/TCP 3m36s
service-test-7 ClusterIP 10.96.0.9 <none> 80/TCP 3m35s
service-test-8 ClusterIP 10.96.0.4 <none> 80/TCP 3m34s
service-test-9 ClusterIP 10.96.0.5 <none> 80/TCP 3m33s
service-test-new-1 ClusterIP 34.118.235.89 <none> 80/TCP 8s
service-test-new-2 ClusterIP 34.118.234.162 <none> 80/TCP 8s
service-test-new-3 ClusterIP 34.118.230.252 <none> 80/TCP 7s
service-test-new-4 ClusterIP 34.118.226.209 <none> 80/TCP 6s
service-test-new-5 ClusterIP 34.118.227.183 <none> 80/TCP 5s
service-test-new-6 ClusterIP 34.118.227.182 <none> 80/TCP 4s
Chimbus-MacBook-Pro:~ chimbu$
Supprimer un ServiceCIDR
Les ServiceCIDR sont protégés par des finalizers pour éviter de laisser des ClusterIP de Service orphelins ; le finalizer n'est retiré que si plus aucune adresse IP n'est attribuée à un service appartenant au sous-réseau.
Vous devez donc d'abord supprimer tous les services Kubernetes qui utilisent des adresses IP du ServiceCIDR, puis supprimer l'objet ServiceCIDR lui-même.
En résumé, à mesure que les clusters Kubernetes grandissent, étendre la plage d'IP de Service devient indispensable pour éviter l'épuisement des IP et préserver une scalabilité fluide. Ces nouvelles fonctionnalités apportent la souplesse dont ont besoin les environnements qui réclament, au fil du temps, davantage d'adresses IP de service, sans risquer le moindre goulet d'étranglement.
J'espère que cet article vous aura apporté des éclairages utiles. Pour en savoir plus ou découvrir nos services, n'hésitez pas à nous contacter ici.