"Autoscaling" indica in Kubernetes tre meccanismi diversi, e confonderli è il motivo più comune per cui un cluster che dovrebbe scalare non lo fa. I pod scalano con un HorizontalPodAutoscaler, i nodi scalano con i limiti dei worker pool e il control plane scala con il carico sull'API. Questo articolo spiega ciascuno di essi, poi illustra un test reale che abbiamo eseguito su un Kube-DC Managed Cluster, con i manifest in modo che tu possa ripeterlo.
Tre cose possono scalare
| Livello | Cosa scala | Su un Kube-DC Managed Cluster |
|---|---|---|
| Pod | Il numero di repliche di un Deployment o StatefulSet, guidato da una metrica come la CPU | HorizontalPodAutoscaler standard, con metrics-server già installato. Testato in questo articolo |
| Nodi | Il numero di macchine worker disponibili per eseguire quei pod | Worker pool con limiti minimo e massimo per pool, come documentato per la piattaforma. Non fa parte del nostro test |
| Control plane | Le risorse di API server ed etcd al crescere del carico del cluster | Autoscaling verticale di entrambi, attivo per impostazione predefinita ed entro limiti configurati, come documentato. Non fa parte del nostro test |
Etichettiamo ogni livello in base a ciò che abbiamo testato e a ciò che conosciamo solo dalla documentazione, perché la differenza conta quando si pianifica la capacità.
Cosa fa davvero l'HorizontalPodAutoscaler
L'HorizontalPodAutoscaler (HPA) è un ciclo di controllo che gira all'interno del control plane di Kubernetes. Per impostazione predefinita si attiva ogni 15 secondi, legge le metriche dei pod a cui è rivolto e regola il numero di repliche del Deployment. Capire quattro dettagli spiega quasi ogni sorpresa:
- L'utilizzo è relativo alla request. Un obiettivo del 50% di CPU significa il 50% della CPU richiesta dai container del pod, non il 50% del nodo. Se un container non ha una request di CPU, l'utilizzo non è definito e l'autoscaler non interviene su quella metrica.
- Ha bisogno della Metrics API. L'API metrics.k8s.io è normalmente fornita dall'add-on Metrics Server, che in un cluster self-managed va installato separatamente.
- Il calcolo è un rapporto. Il numero desiderato di repliche è uguale al numero attuale di repliche moltiplicato per il rapporto tra la metrica attuale e l'obiettivo, arrotondato per eccesso. Se il rapporto rientra in una tolleranza di 0,1 intorno a 1,0, non succede nulla.
- Il downscaling è deliberatamente lento. Il controller ricorda le raccomandazioni recenti e agisce in base alla più alta in una finestra che per impostazione predefinita dura cinque minuti, il che smorza le metriche fluttuanti ed evita oscillazioni.
Per esempio, una replica che gira al 57% di CPU rispetto a un obiettivo del 50% dà un rapporto di 1,14 e, arrotondando per eccesso, 1 × 1,14 dà 2 repliche. È esattamente il primo passaggio che abbiamo osservato nel test qui sotto.
Il test: scalare un Managed Cluster sotto carico reale
Nel nostro test end-to-end di agosto 2026 abbiamo creato un Managed Cluster chiamato test2 con due nodi worker, ciascuno dimensionato a 1 vCPU e 2 GB di memoria per rientrare nel margine rimasto nella quota del pacchetto. L'endpoint API del cluster è privato per impostazione predefinita, quindi lo abbiamo raggiunto dalla Cloud Shell integrata del progetto tramite l'indirizzo di servizio interno del cluster, non da Internet. Entrambi i worker erano Ready e metrics-server era già installato e funzionante, come richiede l'HPA.
Abbiamo distribuito una piccola applicazione web con un HPA che punta al 50% di CPU e con un intervallo da 1 a 6 repliche. Questi sono manifest di esempio con la stessa forma del test; i valori delle request di CPU sono indicativi:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello
spec:
replicas: 1
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
image: nginxdemos/hello
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 64Mi
---
apiVersion: v1
kind: Service
metadata:
name: hello
spec:
selector:
app: hello
ports:
- port: 80
targetPort: 80
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: hello
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: hello
minReplicas: 1
maxReplicas: 6
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
Per generare un carico prolungato abbiamo avviato diversi pod usa e getta all'interno del cluster, ciascuno dei quali invia in ciclo richieste HTTP al servizio. Esegui il primo comando in due o tre shell con nomi diversi e osserva l'autoscaler in un'altra:
kubectl run load-1 --image=busybox:1.36 --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://hello > /dev/null; done"
kubectl get hpa hello --watch
Due note oneste su questo risultato. Non abbiamo cronometrato il downscaling, e la finestra di stabilizzazione predefinita di cinque minuti è il motivo per cui è in ritardo rispetto all'upscaling. Inoltre il test dimostra solo il livello dei pod: mostra che HPA, Metrics API e la pianificazione del cluster funzionano insieme su un Kube-DC Managed Cluster, non come si comportano i worker pool con la scalabilità a livello di nodo.
Quando hai finito, rimuovi il carico con kubectl delete pod load-1 (e con gli altri generatori che hai avviato), poi il carico di lavoro di test con kubectl delete hpa,svc,deploy hello.
Cosa i pod non possono fare da soli: la capacità
L'HPA aggiunge pod, e i pod hanno bisogno di un posto dove girare. Se i worker sono pieni, le repliche in più restano in Pending finché non si rende disponibile capacità, quindi il maxReplicas dell'HPA ha senso solo se il pool sottostante può contenere tanti pod. Moltiplica il numero massimo di repliche per le request di ciascun pod e confronta il risultato con la capacità libera del tuo worker pool.
Su Kube-DC i worker pool sono definiti per pool (CPU, memoria, disco e immagine) con limiti di autoscaling per pool, e il pool attinge alla quota del tuo pacchetto. Questa quota è condivisa in pool su tutto ciò che esegui: container, macchine virtuali e Managed Cluster condividono lo stesso budget di vCPU e memoria. Abbiamo visto la conseguenza nel nostro test, dove un Managed Cluster esistente e una macchina virtuale utilizzavano circa 7,5 delle 8 vCPU di un pacchetto Pro, senza lasciare spazio per un pod GPU. È il motivo per cui abbiamo dimensionato i worker di test a 1 vCPU e 2 GB. Considera il tuo pacchetto come il tetto di ogni livello di scalabilità e verifica il margine residuo prima di alzare un massimo.
Scala anche il control plane
Un cluster con molti pod e scalabilità frequente carica API server ed etcd. La documentazione di Kube-DC afferma che le risorse di control plane ed etcd vengono dimensionate automaticamente in modo adeguato entro limiti configurati al crescere del carico del cluster, con autoscaling verticale attivo per impostazione predefinita. In un cluster self-managed, dimensionare correttamente questi componenti è compito tuo, ed etcd è sensibile alla mancanza di risorse, come spieghiamo nel nostro articolo su Kubernetes managed vs. self-hosted.
Errori comuni
- Nessuna resource request. Senza una request di CPU non è possibile calcolare un obiettivo di utilizzo e l'HPA non fa nulla per quella metrica.
- Ignorare il comportamento all'avvio. Un pod che consuma molta CPU durante l'inizializzazione può innescare upscaling aggiuntivi. La documentazione di Kubernetes raccomanda una startup probe, o una readiness probe che passa solo dopo il picco, e il controller ignora i campioni di CPU di un pod durante il suo periodo di inizializzazione.
- Scalare sulla CPU quando la CPU non è il collo di bottiglia. L'API autoscaling/v2 supporta anche memoria e metriche personalizzate, più adatte ai carichi di lavoro guidati da code o vincolati dall'I/O.
- Impostare il massimo senza verificare la capacità. Come sopra, le repliche oltre ciò che il pool può contenere restano semplicemente in attesa in Pending.
- Eseguire una sola replica in produzione. Un minimo di uno significa un solo pod finché il carico è basso. Usa un minimo più alto per tutto ciò che deve sopravvivere alla perdita di un nodo.
Fonti
- Kubernetes: Horizontal Pod Autoscaling
- Kube-DC platform datasheet: managed Kubernetes clusters
- Kube-DC: provisioning a Managed Cluster
Letture correlate
- Kubernetes managed vs. self-hosted: la realtà tecnica
- Come valutare un provider di Managed Kubernetes in Europa
- GPU condivisa su Kubernetes: cosa ottieni davvero
Esegui questo test sul tuo cluster
Ogni pacchetto Kube-DC include cluster Kubernetes annidati, creati dal tuo progetto in un portale self-service, con metrics-server pronto e la tua quota visibile per pianificare la capacità. Dietro ci sono vCPU dedicate, storage NVMe basato su Ceph, un IPv4 pubblico dedicato e object storage compatibile S3, con supporto 24/7 via email e ticket e un obiettivo di risoluzione di 4 ore. Ripeti la guida qui sopra e guarda tu stesso come si muovono le repliche.
Scopri Kube-DC Kubernetes