Il tuo cluster Kubernetes va in crash quando arriva il traffico del Black Friday? Oppure tieni 20 pod sempre accesi anche quando servono solo 3? Entrambi gli scenari costano: il primo perde clienti e fatturato, il secondo brucia risorse su cloud o server on‑prem. Noi, di Meteora Web, abbiamo visto PMI spendere il 40% in più del necessario su AWS perché l'Horizontal Pod Autoscaler era disabilitato o mal configurato. In questa guida vediamo come usare l'HPA per scalare automaticamente i pod in base al carico reale, senza sprechi e senza sorprese.
Cos'è l'Horizontal Pod Autoscaler di Kubernetes e perché ti serve in produzione?
L'Horizontal Pod Autoscaler (HPA) è un controller nativo di Kubernetes che aumenta o riduce il numero di repliche dei pod in base a metriche come CPU, memoria o richieste HTTP al secondo. Non è un tool esterno: fa parte dell'API autoscaling/v2 e gira dentro il cluster. La domanda vera è: perché dovresti preoccupartene ora? Perché in produzione il carico non è mai lineare. Un e‑commerce potrebbe avere 10 visitatori la mattina e 10.000 alle 18:00. Un backend di prenotazioni esplode durante gli eventi. Se non hai scalabilità automatica, hai due scelte: sovradimensionare (e pagare) o sottodimensionare (e crashare). Noi abbiamo ereditato un cluster con 5 pod fissi per un CRM: a regime bastavano 3, ma durante gli accessi mattutini scoppiavano. Con l'HPA abbiamo risolto in un giorno, risparmiando il 30% sui costi di compute.
Sponsored Protocol
L'HPA non è magia: si basa su metriche raccolte dal Metrics Server (obbligatorio) e agisce modificando il replicas del Deployment o StatefulSet. Puoi configurare target percentuali, valori assoluti, o metriche personalizzate tramite Prometheus adapter. Ma attenzione: un HPA mal regolato fa più danni di nessun autoscaler. Scaling up troppo aggressivo causa burst di costi e instabilità; scaling down troppo lento mantiene risorse inutilizzate. La chiave è bilanciare reattività e stabilità.
Come configurare l'Horizontal Pod Autoscaler Kubernetes con CPU e memoria?
Partiamo dal caso più comune: CPU utilisation come metrica. Supponiamo un Deployment chiamato my-api con resources.requests.cpu: 250m e limits: 500m. Creiamo un file hpa.yaml:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-api
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Applichiamo con kubectl apply -f hpa.yaml. L'HPA calcolerà il numero di repliche necessario per mantenere la CPU media al 70% e la memoria all'80%. Se il carico sale, scalerà fino a 10 pod; se scende, tornerà a 2. Attenzione: senza resources.requests nei container, l'HPA non funziona perché non sa su quale base calcolare la percentuale. È uno degli errori più comuni che vediamo in audit.
Sponsored Protocol
Per verificare lo stato: kubectl get hpa my-api-hpa -w mostra target, current e repliche in tempo reale. Se vedi <unknown> nei target, probabilmente manca Metrics Server. Installalo con kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml (su cloud spesso è già attivo).
Quali metriche avanzate usare per l'Horizontal Pod Autoscaler?
CPU e memoria vanno bene per carichi general‑purpose, ma per applicazioni web o API la metrica migliore è il numero di richieste al secondo (RPS). Qui entrano in gioco metriche personalizzate tramite Prometheus Adapter o KEDA (sponsorizzato da Microsoft). Noi preferiamo KEDA perché gestisce anche code di eventi (Kafka, RabbitMQ) e scheduler più sofisticati.
Esempio di HPA con metrica Prometheus: supponiamo di avere una metrica http_requests_total. Con KEDA si crea uno ScaledObject:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: api-scaler
spec:
scaleTargetRef:
name: my-api
minReplicaCount: 2
maxReplicaCount: 20
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus.monitoring.svc:9090
metricName: http_requests_per_second
query: |
sum(rate(http_requests_total{job="my-api"}[1m]))
threshold: '100'
activationThreshold: '10'
Con threshold: 100, KEDA scalerà quando il rate supera 100 req/s per pod. activationThreshold evita scale‑up su rumore. Noi abbiamo usato questa configurazione per un cliente logistica: le notifiche degli ordini arrivano a burst, ma con KEDA scaliamo in 30 secondi e poi scendiamo rapidamente. Risultato: nessun timeout e fattura AWS ridotta del 45% rispetto a replica fissa.
Sponsored Protocol
Come testare l'Horizontal Pod Autoscaler prima di andare in produzione?
Non fidarti della teoria. Carica il cluster con un tool di stress test e osserva. Noi usiamo kubectl run -i --tty load-generator --image=busybox /bin/sh e poi lanciamo while true; do wget -q -O- http://my-api-svc; done. In alternativa, usa hey (https://github.com/rakyll/hey) su un nodo esterno: hey -n 10000 -c 50 http://my-api-svc.cluster.local.
Monitora con kubectl top pods e kubectl describe hpa my-api-hpa. Controlla i log dell'HPA controller con kubectl logs -n kube-system deployment/kube-controller-manager | grep -i hpa (su cluster on‑prem). Se noti scaling troppo rapido, aggiungi behavior nella spec dell'HPA per stabilizzare:
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
Questo blocca la discesa per 5 minuti (evita flapping) e permette scale‑up aggressivo. Noi lo abbiamo applicato a un cliente e‑commerce: durante il picco di Natale l'HPA è passato da 3 a 30 pod in 45 secondi senza impazzire.
Sponsored Protocol
Come ottimizzare l'Horizontal Pod Autoscaler per ridurre i costi?
Un HPA che scala troppo spesso o troppo alto costa. Tre accorgimenti pratici:
- Usa minReplicas realistici: mai lasciare a 1 se hai bisogno di ridondanza. Noi impostiamo sempre almeno 2 per carichi critici.
- Abbina il Vertical Pod Autoscaler (VPA) per regolare i request/limit in base all'uso reale, così l'HPA lavora su metriche più accurate. Attenzione: VPA e HPA sullo stesso deployment confliggono se non gestiti bene. Preferisci VPA in modalità
Offche solo suggerisce. - Imposta target di CPU più alti (es. 80% invece di 50%) se l'applicazione è stateless e tollera picchi brevi. Meno repliche spente, meno risparmi – ma attento ai timeout. Noi abbiamo un cliente SaaS che tiene CPU target al 90% con HPA e risparmia il 25% sul cloud. Funziona perché il codice è ottimizzato.
Ricorda: l'HPA non è solo per risparmiare, è per non perdere fatturato. Come diciamo sempre ai nostri clienti: un sito che va giù durante una campagna pubblicitaria costa molto più di qualche pod extra.
Errori comuni con l'Horizontal Pod Autoscaler Kubernetes (e come evitarli)
- Metriche non disponibili: il Metrics Server non installato o non raggiungibile. Verifica con
kubectl top nodes. - Resource request non impostati: l'HPA ignora i pod senza request. Ogni container DEVE avere
resources.requests. - Stabilization window troppo bassa: causa flapping (scala su e giù continuamente). Imposta almeno 2–3 minuti per scaleDown.
- Ignorare i limiti di quota a livello di namespace: se il namespace ha un
ResourceQuota, l'HPA non può superare quel limite. Controlla conkubectl describe quota. - Non testare in staging: abbiamo visto clienti applicare HPA direttamente in produzione con target sbagliati e mandare in crash il sistema. Simula sempre con carico artificiale.
In sintesi
L'Horizontal Pod Autoscaler di Kubernetes è uno strumento potente, ma richiede attenzione ai dettagli. Ecco cosa puoi fare subito:
Sponsored Protocol
- Attiva Metrics Server sul tuo cluster se non presente.
- Imposta resource request su tutti i container del deployment target.
- Crea un primo HPA con CPU al 70%, minReplicas 2 e maxReplicas 10.
- Testa con un carico artificiale e regola i parametri di comportamento.
- Monitora i costi: confronta il numero di pod prima e dopo su un periodo di 7 giorni.
Se gestisci un cluster Kubernetes, l'HPA non è un optional: è la differenza tra un sistema che regge e uno che crolla. Noi, di Meteora Web, lo usiamo quotidianamente per i nostri clienti. Per approfondire l'intero ecosistema Kubernetes, leggi la nostra guida pillar su Kubernetes e Orchestrazione Container. Per dubbi specifici, scrivici: risolviamo insieme.