Quando dovrei usare la scalabilità automatica orizzontale dei pod (HPA) in Kubernetes?

Risposta breve: usa l'HPA quando il tuo carico di lavoro può eseguire più repliche identiche e la domanda varia, con scalabilità basata su CPU/memoria, metriche dell'applicazione (RPS/latenza) o metriche esterne della coda o dell'arretrato. Non usare HPA per i servizi stateful con una sola replica o quando il vero collo di bottiglia è la capacità del nodo o le limitazioni dei sistemi a valle (connessioni al database, limiti di velocità imposti da terze parti).

TL;DR:

  • Usare HPA per carichi di lavoro partizionabili orizzontalmente in cui le metriche relative ai pod o le metriche esterne riflettono il carico.
  • Usa metriche delle risorse/personalizzate/esterne (CPU, RPS, profondità della coda); combina con Cluster Autoscaler per la capacità dei nodi.
  • Usare KEDA per la scalabilità fino a zero guidata dagli eventi o per scaler esterni; usare VPA in modalità raccomandazione per dimensionare le richieste.

Elenco di controllo rapido per le decisioni (Sì/No):

  • Il carico di lavoro è privo di stato o partizionabile tra molte repliche? (Sì → candidato HPA)
  • È possibile osservare il carico come metrica per pod o come metrica esterna (CPU, richieste/sec, profondità della coda)? (Sì → HPA idoneo)
  • Il cluster può allocare altri pod (Cluster Autoscaler o capacità disponibile)? (Sì → procedere; se No, abilitare la scalabilità automatica dei nodi)
  • I servizi downstream (pool di database, API di terze parti) limitano la concorrenza? (Sì → aggiungere limitazioni/pool di connessioni o preferire il ridimensionamento verticale)

Matrice decisionale (carico di lavoro → migliore metrica → scaler consigliato):

Tipo di carico di lavoro Metrica ottimale per la destinazione Scaler consigliato
Web/API (senza stato) CPU o RPS per pod HPA (+raccomandazione VPA + Scalabilità automatica del cluster)
Worker della coda in background Lunghezza della coda o messaggi/sec HPA tramite metriche esterne o KEDA (KEDA supporta la scalabilità a zero)
Database a istanza singola o applicazione con stato N/D (non partizionabile in orizzontale) VPA o ridimensionamento manuale
Ruoli di lavoro per eventi batch/temporanei Backlog degli eventi KEDA o HPA con metriche esterne

Funzionamento di HPA (semplice ciclo di controllo e campi importanti)

  • Componenti: il controller HPA (piano di controllo) + i provider di metriche (metrics-server per le metriche delle risorse, l'API delle metriche personalizzate/esterne tramite adattatori o KEDA).
  • Ciclo di controllo (livello generale): il controller HPA interroga periodicamente l'API delle metriche → calcola il numero desiderato di repliche per ogni metrica configurata → seleziona il valore calcolato più alto del numero desiderato di repliche → applica i valori min/max e il comportamento di scalabilità (criteri/stabilizzazione) → aggiorna spec.replicas nella risorsa di destinazione → ripete. Per informazioni dettagliate, vedere la documentazione di HPA di Kubernetes .
  • Formula (modalità di calcolo delle repliche desiderate): desiredReplicas = ceil(current_total/target_per_pod). Il controller calcola un valore desiredReplicas per ogni metrica configurata, quindi usa il valore più grande prima di applicare min/max e il comportamento (questo comportamento di precedenza della metrica è documentato nella documentazione HPA).
  • Campi importanti per il ridimensionamento automatico/v2: minReplicas, maxReplicas, metriche (Resource, Pods, Object, External), comportamento (criteri scaleUp/scaleDown e stabilizationWindowSeconds).
  • Usa il comportamento per limitare il tasso di variazione ed evitare il flapping; stabilizationWindowSeconds è un parametro chiave per l’attenuazione dello scaleDown.

Frammento di comportamento di esempio (scalabilità automatica/v2)

behavior:
  scaleUp:
    stabilizationWindowSeconds: 0
    policies:
      - type: Percent
        value: 100
        periodSeconds: 60
  scaleDown:
    stabilizationWindowSeconds: 300
    policies:
      - type: Pods
        value: 1
        periodSeconds: 60

Quando usare HPA (per tipo di metrica/casi d'uso comuni)

  1. CPU/memoria (metriche delle risorse)
    • Usare HPA quando l'utilizzo della CPU o della memoria per pod è correlato alle esigenze di capacità e i pod definiscono richieste di risorse corrette. Tipico per le API Web e i microservizi senza stato.
    • Punto di partenza pratico: usare l'utilizzo medio della CPU nell'intervallo di 60-80% e ottimizzare i test di carico. HPA calcola l'utilizzo dalle richieste dei pod, quindi le richieste devono essere impostate.
  2. Metriche personalizzate nel cluster (Prometheus/metriche personalizzate)
    • Usare HPA quando i segnali a livello di app (richieste/sec, latenza, consumer di coda/pod) rappresentano meglio il carico rispetto alla CPU.
    • Esporre le metriche con Prometheus + prometheus-adapter (custom.metrics.k8s.io) o un altro provider di metriche personalizzato e specificare come destinazione tali metriche in HPA.
  3. Metriche esterne (code, backlog nel cloud)
    • Usare HPA (tramite l'API delle metriche esterne) o KEDA quando il ridimensionamento deve reagire a segnali esterni come la lunghezza della coda (RabbitMQ, bus di servizio di Azure), Hub eventi o metriche di monitoraggio cloud.
    • Se hai bisogno della scalabilità fino a zero o di un comportamento strettamente guidato dagli eventi, è preferibile KEDA, che integra nativamente scaler esterni e supporta la scalabilità fino a zero (documentazione KEDA).

Quando NON usare HPA

  • Servizi con stato a replica singola (database, stato univoco interno al pod): HPA non è appropriato a meno che non si possa eseguire lo sharding o il partizionamento in modo sicuro.
  • Quando il collo di bottiglia è a livello di nodo (GPU, I/O del disco, CPU del nodo) anziché a livello di singolo pod: preferite l'autoscaling del pool di nodi o la scalabilità verticale.
  • Quando i sistemi downstream (pool di connessioni db, cache, API di terze parti) hanno limiti di concorrenza rigorosi: il ridimensionamento dei pod senza aumentare la capacità downstream può peggiorare gli errori. Vedere "Considerazioni operative e downstream" di seguito.
  • Se è necessario scalare a zero, l'HPA normale non può ottenere questo risultato; usare KEDA o un controller esterno.

Più metriche, precedenze e un esempio

  • Se configuri più metriche, il controller HPA calcola un valore desiredReplicas per ciascuna metrica in modo indipendente e quindi seleziona il valore desiredReplicas più alto come base per il ridimensionamento. Dopo di che, vengono applicati minReplicas/maxReplicas e le policy di comportamento (origine: la documentazione di Kubernetes HPA).
  • Esempio: l'obiettivo CPU calcola 5 repliche, l'obiettivo richieste/sec ne calcola 12 → HPA sceglierà 12 (dopodiché i criteri min/max e di comportamento possono modificare la variazione finale applicata).
  • Per evitare un sovraccarico improvviso, combinare un criterio scaleUp basato su percentuale e una stabilizzazione scaleDown ragionevoleWindowSeconds (vedere il frammento di comportamento precedente).

HPA vs VPA vs Cluster Autoscaler vs KEDA (indicazioni brevi)

  • HPA: ridimensiona orizzontalmente le repliche in base alle metriche. Ideale per carichi di lavoro partizionabili.
  • VPA: regola le richieste/limiti delle risorse dei pod (verticale). Ideale per carichi di lavoro non parallelizzabili o per impostare valori predefiniti sensibili.
  • Scalabilità automatica del cluster (o Karpenter): ridimensiona i nodi per soddisfare le richieste di pianificazione (capacità a livello di nodo). Usare quando i pod rimangono nello stato Pending a causa dell'assenza di nodi.
  • KEDA: scalabilità automatica guidata dagli eventi che integra trigger esterni e supporta la scalabilità a zero per i carichi di lavoro degli eventi.

Modello comune: usare VPA in modalità raccomandazione per impostare le richieste di base, HPA per ridimensionare le repliche e Cluster Autoscaler (o Karpenter) per fornire capacità del nodo. Utilizza KEDA quando hai bisogno della scalabilità fino a zero o dell'integrazione diretta con sorgenti di eventi esterne.

Nota: le offerte Kubernetes gestite (AKS/GKE/EKS) possono preinstallare i provider di metriche o fornire funzionalità integrate di scalabilità automatica. Documentazione di Cluster Autoscaler di AKS


Considerazioni a valle e operative (criticità comuni)

  • Pool di connessioni di database: l'aumento delle repliche aumenta le connessioni simultanee. Mitigare tramite il pooling delle connessioni (ad esempio, PgBouncer), limitare la concorrenza per pod o aumentare la dimensione del pool di connessioni al database prima di scalare i pod.
  • Limiti di velocità delle API e quote di servizi di terze parti: assicurarsi che i sistemi a valle possano gestire il volume di richieste generato dai pod scalati; valutare la limitazione della frequenza sul lato client.
  • PodDisruptionBudgets (PDB): i PDB non impediscono il ridimensionamento di HPA, ma possono influire sulle operazioni di manutenzione e sul comportamento di svuotamento; assicurarsi che i criteri di ridimensionamento siano allineati ai PDB.
  • Effetti di avvio e riscaldamento: initContainers, riscaldamento cache o avvio a freddo lungo può asimmetrie metriche e causare oscillazioni: usare probe di preparazione/avvio e finestre di stabilizzazione.
  • Approccio operativo consigliato: impostare velocità di scalabilità conservative, regolare richieste/limiti e le sonde, testare in ambienti non di produzione e aggiungere una limitazione del traffico basata sugli SLO se i sistemi a valle rappresentano un collo di bottiglia.

Elenco di controllo di configurazione e passaggi di implementazione sicuri

Assicurarsi che le metriche e RBAC (controllo degli accessi basato sui ruoli) siano configurati correttamente:

  • Distribuire metrics-server per le metriche delle risorse (o usare il provider gestito).
  • Distribuire Prometheus + prometheus-adapter per le metriche personalizzate (custom.metrics.k8s.io) se necessario.
  • Per i sistemi di scalabilità esterni/eventi, prendere in considerazione KEDA.

Scrivi HPA (autoscaling/v2) con:

  • minReplicas e maxReplicas,
  • metriche e comportamenti espliciti (criteri scaleUp/scaleDown),
  • preparazione e probe di avvio nei pod,
  • richieste di risorse sensibili in modo che le metriche delle risorse siano significative.

Elenco di controllo per i test sicuri (come testare HPA in modo sicuro):

  1. Eseguire il test in uno spazio dei nomi/cluster non di produzione con dimensioni del nodo simili e scalabilità automatica abilitata.
  2. Inizia con repliche minime/massime conservative e criteri di scalabilità verso l’alto graduali (ad esempio, massimo 100% di crescita al minuto).
  3. Eseguire test di carico graduali, monitorare desiredReplicas rispetto a currentReplicas e i pod in stato Pending.
  4. Eseguire l'iterazione su richieste/limiti, probe di idoneità e criteri di comportamento prima di aumentare l'aggressività.

Note su AKS e sulla scalabilità automatica dei nodi:

  • AKS e altre offerte cloud possono preinstallare metrics-server o offrire l'integrazione gestita dell'autoscaler. Esempio di CLI di AKS per abilitare l'autoscaler del cluster: az aks nodepool update --resource-group myRG --cluster-name myAKS --name node-pool1 --enable-cluster-autoscaler --min-count 1 --max-count 5

Nota su Karpenter: Karpenter è un approccio alternativo all’auto-scaling dei nodi, incentrato sul provisioning rapido; da considerare quando è richiesto il provisioning rapido dei nodi.


Esempi YAML funzionanti

HPA basato sulla CPU (scalabilità automatica/v2):

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: webapi-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: webapi
  minReplicas: 3
  maxReplicas: 12
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Pods
          value: 1
          periodSeconds: 60

HPA usando una metrica personalizzata esposta da Prometheus (tramite prometheus-adapter):

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-requests-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Pods
      pods:
        metric:
          name: http_requests_per_second
        target:
          type: AverageValue
          averageValue: "100"

Consulta la documentazione di prometheus-adapter per le query di mappatura

KEDA ScaledObject (bus di servizio di Azure): supporta la scalabilità a zero:

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: sb-queue-scaledobject
  namespace: workers
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: event-worker
  minReplicaCount: 0
  maxReplicaCount: 20
  pollingInterval: 30
  cooldownPeriod: 300
  triggers:
    - type: azure-servicebus
      metadata:
        queueName: orders-queue
        queueLength: "50"
      authenticationRef:
        name: keda-azure-credentials

Documentazione su KEDA


Esempi di osservabilità, avvisi e SRE

Avvisi suggeriti (esempi copiabili di Prometheus, modifica i nomi delle metriche per la configurazione dell'esportazione):

  1. Avvisare quando HPA desidera corrente > per > 5 m (problema di capacità di pianificazione)

    alert: HPAUnschedulable
    expr: (kube_hpa_status_desired_replicas - kube_hpa_status_current_replicas) > 0
    for: 5m
    labels:
      severity: page
    annotations:
      summary: "HPA desired replicas exceed current replicas for >5m (possible scheduling issue)"
    
  2. Avviso per i pod in sospeso in uno spazio dei nomi

    alert: PodsPendingHigh
    expr: sum(kube_pod_status_phase{phase="Pending", namespace="production"}) > 3
    for: 2m
    labels:
      severity: ticket
    annotations:
      summary: "High number of Pending pods in production"
    
  3. Avviso in caso di ridimensionamento frequente (flapping)

    alert: HPAFlapping
    expr: increase(kube_hpa_status_replicas_last_transition_count[10m]) > 5
    for: 0m
    labels:
      severity: warning
    annotations:
      summary: "Frequent HPA scaling events detected"
    

Cruscotti degli strumenti che mostrano:

  • HPA: currentReplicas, desiredReplicas, lastScaleTime, valori delle metriche usati da HPA
  • Integrità dei pod: pod in sospeso, eventi FailedScheduling, numero di riavvii dei pod
  • Downstream: utilizzo delle connessioni DB, tassi di errore, tassi di errore dell'API esterna e dei 429

Comandi operativi e di debug (riferimento rapido)

  • Elencare gli HPA: kubectl get hpa -n
  • Descrivi HPA (cerca metriche correnti, desiredReplicas, lastScaleTime, events): kubectl describe hpa -n
  • Campi da esaminare nell'output descritto: currentReplicas, desiredReplicas, metrics (valori correnti/di destinazione), lastScaleTime, eventi (errori del provider di metriche o errori di ridimensionamento)
  • Visualizzare l'utilizzo delle risorse (richiede metrics-server): kubectl top pods -n
  • Controllare i pod in sospeso e gli errori di pianificazione: kubectl get pods -n | grep Pending, kubectl describe pod -n (cercare FailedScheduling)
  • Verificare i log del provider di metriche: kubectl logs -n kube-system deploy/metrics-server, kubectl logs -n deploy/prometheus-adapter
  • Applicare il manifesto HPA: kubectl apply -f hpa.yaml

Suggerimenti rapidi per la risoluzione dei problemi:

  • HPA segnala desiredReplicas > currentReplicas e i pod restano in stato Pending → probabile capacità insufficiente dei nodi; abilitare Cluster Autoscaler o aumentare il pool di nodi.
  • HPA mostra errori delle metriche negli eventi → controlla RBAC/configurazione dell'adattatore e i log del provider di metriche.
  • Lo scaling HPA è troppo veloce/lento → regolare le policy di comportamento (limiti percentuali/per numero di pod) e le finestre di stabilizzazione.

  • Obiettivo CPU: iniziare con un utilizzo medio di circa il 60% (intervallo tipico 60–80%) e regolare in base al carico di lavoro.
  • minReplicas: almeno 1 per garantire la disponibilità; utilizzare KEDA se è necessario minReplicas: 0.
  • maxReplicas: impostato in base alla pianificazione e al costo della capacità; assicurarsi che i limiti di scalabilità automatica del cluster consentano l'aggiunta di nodi fino alla capacità necessaria.
  • stabilizationWindowSeconds: scaleDown ≈ 300s (5 minuti) è un punto di partenza comune per evitare ridimensionamenti rapidi; regolare in base al carico di lavoro.
  • politiche di scalabilità: limitare gli aumenti percentuali per periodo (ad esempio, consentire una crescita massima del 100% al minuto) per evitare di sovraccaricare i sistemi a valle.
  • Probe di readiness/startup: definitele sempre in modo che i pod non ricevano traffico finché non sono completamente pronti.

Nota: le impostazioni predefinite specifiche del controller e il comportamento esatto possono variare a seconda delle versioni e delle distribuzioni di Kubernetes — consulta la documentazione HPA relativa alla versione del tuo cluster


Problemi comuni e elenco di controllo prima di abilitare HPA

  • Richieste di risorse dei pod mancanti o errate → gli obiettivi HPA basati sulle risorse saranno fuorvianti.
  • Nessun provider di metriche (metrics-server/prometheus-adapter/KEDA) → HPA non può leggere le metriche.
  • Il cluster non ha capacità dei nodi e Cluster Autoscaler non è abilitato → i pod rimarranno in stato Pending.
  • Uso combinato di HPA e VPA: evitare che entrambi i controller modifichino attivamente le richieste di risorse; eseguire VPA in modalità di raccomandazione e lasciare che HPA ridimensioni le repliche.
  • Picchi all'avvio (initContainers, cache a freddo) senza probe → regolare le finestre di stabilizzazione o preriscaldare manualmente le istanze.
  • Configurazione errata di RBAC: assicurarsi che gli adattatori di metriche e il controller HPA dispongano delle autorizzazioni necessarie per leggere le metriche.

Domande frequenti rapide

D: Quali sono i vantaggi di HPA? A: Adattare automaticamente il numero di repliche alle variazioni del carico, migliorare l'utilizzo e ottimizzare i costi, e mantenere gli obiettivi di latenza se usati con le metriche corrette e l'autoscaling dei nodi.

D: In che modo HPA calcola le repliche desiderate? R: Legge le metriche configurate, calcola desiredReplicas = ceil(current_total/target_per_pod) per ogni metrica, accetta il valore calcolato più grande, quindi applica i criteri di comportamento min/max (origine: documentazione HPA).

D: È possibile ridimensionare HPA su zero? A: No — un HPA standard non può scalare fino a zero. Usare KEDA per il comportamento da scala a zero (documentazione KEDA).

Q: Come eseguire il ridimensionamento in base alla lunghezza della coda o al valore RPS? R: Esporre la lunghezza della coda/RPS come metrica esterna o personalizzata (adattatore Prometheus o API metriche esterne) o usare KEDA per il ridimensionamento basato su eventi.


References