Quando si gestiscono cluster Kubernetes, garantire un numero sufficiente di indirizzi IP per i Service Kubernetes diventa un aspetto critico per scalare e mantenere la propria infrastruttura.
I Service offrono un modo astratto per esporre un'applicazione in esecuzione su un insieme di Pod. I diversi tipi di Service, come ClusterIP, NodePort e LoadBalancer, utilizzano un indirizzo IP virtuale univoco a livello di cluster, denominato ClusterIP.
L'indirizzo ClusterIP di ciascun Service deve essere univoco all'interno dell'intero cluster. Tentare di creare un Service con un ClusterIP già allocato genera un errore. Con la crescita del deployment, l'intervallo IP predefinito per i Service può rivelarsi insufficiente e creare colli di bottiglia nelle risorse di rete.
In passato non era possibile ridimensionare o ampliare gli intervalli di IP assegnati ai Service: di qui i problemi in caso di reti sovrapposte o di esaurimento degli IP disponibili nel cluster.
Tuttavia, il kube-apiserver con il feature gate MultiCIDRServiceAllocator abilitato e l'API networking.k8s.io/v1alpha1 consentono di espandere dinamicamente il numero di IP disponibili per i Service. La funzionalità è passata allo stadio beta in Kubernetes 1.31 e si raccomanda di attenderne la promozione a Stable prima di adottarla in produzione. Per maggiori dettagli sull'implementazione, si rimanda a KEP-1880—Multiple Service CIDRs.
In questo articolo vedremo come estendere l'intervallo IP dei Service in un cluster Google Kubernetes Engine (GKE). È inoltre possibile testare la funzionalità su altre distribuzioni Kubernetes, consultando le note di rilascio specifiche per i dettagli di configurazione e le eventuali limitazioni.
Prerequisiti
Occorre un cluster GKE con versione 1.31.1-gke.1361000 o successiva e accertarsi che lo strumento da riga di comando kubectl sia configurato per comunicare con il cluster.
Abilitare e verificare le API beta
A partire da Kubernetes 1.24, le nuove API beta sono disabilitate per impostazione predefinita nei nuovi cluster GKE. I cluster esistenti creati con una versione precedente alla 1.24 mantengono abilitate le API beta già presenti.
È possibile abilitare le API beta in fase di creazione del cluster oppure in un secondo momento. Per abilitare quelle richieste, seguire le istruzioni in Use Kubernetes beta APIs with GKE clusters.
Esempio di comando per abilitare le API beta richieste su un cluster esistente:
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>>
Le API appena abilitate creeranno un oggetto ServiceCIDR con il nome convenzionale kubernetes e un intervallo di indirizzi IP basato sul CIDR iniziale dei Service.
Per verificare il nuovo oggetto ServiceCIDR, eseguire il comando seguente:
Chimbus-MacBook-Pro:~ chimbu$ kubectl get servicecidr
NAME CIDRS AGE
kubernetes 10.96.0.0/28 98m
Chimbus-MacBook-Pro:~ chimbu$
Aggiungere un nuovo ServiceCIDR
A scopo di test, ho creato un cluster con un intervallo /28 per i Service, che contiene solo 14 indirizzi IP. Il Service kubernetes.default viene sempre creato; in questo esempio rimangono quindi solo 13 Service possibili.
A scopo di test, ho creato un cluster con un intervallo /28 per i Service che contiene solo 14 indirizzi IP. Il Service kubernetes.default viene sempre creato, lasciando disponibili solo 13 Service.
Provando a creare ulteriori Service Kubernetes, una volta esauriti tutti gli indirizzi IP dell'intervallo la richiesta fallirà con un errore interno.
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$
A questo punto è possibile aumentare il numero di indirizzi IP disponibili per i Service creando un nuovo ServiceCIDR che estende o aggiunge nuovi intervalli.
Durante la fase beta, GKE consente di creare Service CIDR esclusivamente all'interno dell'intervallo IP riservato
34.118.224.0/20, così da evitare possibili sovrapposizioni tra intervalli di indirizzi IP.
Applicare il manifest seguente per creare un nuovo ServiceCIDR che aggiunge un nuovo intervallo di indirizzi 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$
Provando a creare nuovi Service Kubernetes, il ClusterIP verrà assegnato a partire da questo nuovo intervallo.
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$
Eliminare un ServiceCIDR
I ServiceCIDR sono protetti tramite finalizer per evitare di lasciare orfani i ClusterIP dei Service: il finalizer viene rimosso solo quando nessun indirizzo IP risulta assegnato ad alcun Service appartenente alla subnet.
Occorre quindi eliminare prima tutti i Service Kubernetes che utilizzano indirizzi IP del ServiceCIDR e poi rimuovere l'oggetto ServiceCIDR.
In sintesi, con la crescita dei cluster Kubernetes, ampliare l'intervallo IP dei Service è fondamentale per evitare l'esaurimento degli indirizzi e garantire una scalabilità fluida. Le nuove funzionalità offrono flessibilità agli ambienti che, nel tempo, richiedono ulteriori indirizzi IP per i Service, senza il rischio di colli di bottiglia sulle risorse.
Mi auguro che questo articolo le sia stato utile. Per approfondire o per saperne di più sui nostri servizi, non esiti a contattarci qui.