Cloud

Kubernetes Resource: Limits, Requests e HPA in Produzione

Kubernetes Resource: Limits, Requests e HPA in Produzione

Kubernetes Resource Management: Checklist Limits, Requests e HPA in Produzione

La gestione efficiente delle risorse in Kubernetes è la pietra angolare di qualsiasi infrastruttura cloud-native stabile e performante. Ignorare questo aspetto può trasformare un ambiente dinamico e resiliente in un campo minato di instabilità e downtime inattesi. Immaginate uno scenario: un cluster Kubernetes ben dimensionato, con decine di deployment che gestiscono carichi di lavoro critici. Tutto sembra funzionare a dovere, finché un singolo pod, magari a causa di un memory leak o di un picco di traffico inatteso, inizia a consumare risorse in modo spropositato. Senza i giusti controlli, questo pod può saturare completamente un nodo, portando all’eviction forzata di tutti gli altri pod che vi risiedono. Questo non è un esercizio teorico; ho assistito personalmente a un cluster con 30 deployment che è andato in downtime per 20 minuti, proprio a causa di un pod con memory leak che ha saturato la RAM del nodo. La causa? La mancanza di appena cinque righe di configurazione YAML relative ai resource limits. Un errore banale che ha avuto un impatto significativo sulla disponibilità del servizio. Questo articolo vuole essere una guida pratica e una checklist operativa per configurare correttamente requests, limits, QoS classes e autoscaling, garantendo stabilità e performance al tuo ambiente Kubernetes in produzione.

Testato su: Kubernetes 1.29 · kubectl 1.29 · 27 luglio 2026

Prerequisiti / Ambiente di test

Per seguire questa guida, avrai bisogno di un cluster Kubernetes funzionante e accesso con kubectl. Non è necessario un ambiente di produzione, un cluster locale come Minikube o Kind è sufficiente per testare i concetti. Assicurati di avere kubectl configurato e autenticato al tuo cluster.

1. Requests e Limits: Differenza e Perché Entrambi Sono Obbligatori

La distinzione tra requests e limits è fondamentale per la stabilità e l’efficienza del tuo cluster Kubernetes. Questi due parametri, definiti per CPU e memoria, guidano lo scheduler di Kubernetes nel posizionare i pod sui nodi e il kubelet nel gestire le risorse sul nodo.

  • Requests: Indicano la quantità minima di risorse (CPU e memoria) che un pod richiede per funzionare correttamente. Lo scheduler usa le requests per decidere su quale nodo posizionare un pod, garantendo che il nodo abbia abbastanza risorse disponibili per soddisfare questa richiesta minima. Se un nodo non ha le risorse richieste, il pod non verrà schedulato su quel nodo. Leggi anche: Kubernetes Networking: DNS, Services, Ingress — Guida Pratica Sysadmin (2026)
  • Limits: Rappresentano la quantità massima di risorse (CPU e memoria) che un pod può consumare. Se un pod tenta di superare il suo limit di memoria, verrà terminato (OOMKilled – Out Of Memory Killed) dal kubelet. Se supera il limit di CPU, la sua esecuzione verrà throttlata, ma non verrà terminato. Le limits sono cruciali per prevenire che un singolo pod “affami” gli altri pod sul nodo, o addirittura causi instabilità all’intero nodo, come nell’esempio del memory leak che ho menzionato.

Perché entrambi sono obbligatori? Senza requests, Kubernetes non può garantire una base minima di risorse, portando a sovra-provisioning e instabilità. Senza limits, un pod malfunzionante può compromettere l’intero nodo. La combinazione di entrambi fornisce allo scheduler e al kubelet le informazioni necessarie per una gestione delle risorse prevedibile e robusta.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp-container
        image: nginx:latest
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m" # 0.25 CPU core
          limits:
            memory: "128Mi"
            cpu: "500m" # 0.5 CPU core

2. QoS Classes: Guaranteed, Burstable, BestEffort

Kubernetes assegna a ogni pod una Quality of Service (QoS) Class in base alla configurazione delle sue requests e limits. Questa classe determina la priorità di schedulazione e, soprattutto, la gestione dell’eviction in situazioni di scarsità di risorse sul nodo.

  • Guaranteed: Un pod è Guaranteed se le requests di CPU e memoria sono uguali ai limits per tutti i suoi container. Questi pod hanno la massima priorità e sono gli ultimi a essere terminati in caso di risorse insufficienti sul nodo.
  • Burstable: Un pod è Burstable se ha almeno una request di CPU o memoria configurata, e le requests sono inferiori ai limits (o i limits non sono specificati). Questi pod hanno una priorità intermedia e possono essere terminati prima dei pod Guaranteed.
  • BestEffort: Un pod è BestEffort se nessuno dei suoi container specifica requests o limits per CPU o memoria. Questi pod hanno la priorità più bassa e sono i primi a essere terminati in caso di scarsità di risorse.

Comprendere le QoS Classes è cruciale per la resilienza. Assegna Guaranteed ai carichi di lavoro critici, Burstable per la maggior parte delle applicazioni e BestEffort solo per servizi non essenziali o batch job che possono tollerare interruzioni.

3. LimitRange e ResourceQuota per Namespace

In ambienti multi-tenant o con team diversi che condividono un cluster, è essenziale imporre policy sull’utilizzo delle risorse a livello di namespace. LimitRange e ResourceQuota sono gli strumenti per farlo.

apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-mem-limit-range
spec:
  limits:
  - default:
      cpu: 500m
      memory: 256Mi
    defaultRequest:
      cpu: 200m
      memory: 128Mi
    type: Container
  • ResourceQuota: Limita il consumo totale di risorse per un intero namespace. Puoi limitare il numero di pod, servizi, volumi persistenti, e soprattutto, il totale di requests e limits per CPU e memoria. Questo previene che un singolo namespace monopolizzi le risorse del cluster.
kubectl apply -f - <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-quota
spec:
  hard:
    requests.cpu: '4'
    requests.memory: 8Gi
    limits.cpu: '8'
    limits.memory: 16Gi
EOF

Questi strumenti, se ben configurati, ti permettono di dormire sonni più tranquilli, sapendo che i team non potranno involontariamente (o intenzionalmente) causare problemi a tutto il cluster.

4. HPA — Autoscaling Basato su CPU e Metriche Custom

L’Horizontal Pod Autoscaler (HPA) è un controller che scala automaticamente il numero di repliche di un Deployment, ReplicaSet o StatefulSet in base all’utilizzo osservato di CPU, memoria o altre metriche custom. Questo ti permette di gestire i picchi di carico senza intervento manuale.

L’HPA monitora le metriche tramite l’API metrics.k8s.io (che richiede il metrics-server installato) o API esterne per metriche custom. Quando l’utilizzo medio delle risorse di un pod supera una soglia definita, l’HPA aumenta il numero di repliche. Quando scende, le riduce.

Esempio di HPA basato su CPU:

kubectl autoscale deployment myapp --cpu-percent=70 --min=2 --max=10

Questo comando crea un HPA che manterrà l’utilizzo medio della CPU del deployment myapp al 70%, scalando tra un minimo di 2 e un massimo di 10 pod. Puoi verificare lo stato dell’HPA con:

kubectl get hpa

Per metriche custom, come il numero di richieste HTTP al secondo o la lunghezza di una coda di messaggi, è necessario integrare un sistema di monitoraggio come Prometheus e configurare un Custom Metrics API per esporre queste metriche all’HPA.

5. VPA — Vertical Autoscaling per Ottimizzare le Richieste

Mentre l’HPA scala orizzontalmente (aggiungendo o rimuovendo pod), il Vertical Pod Autoscaler (VPA) scala verticalmente, regolando dinamicamente le requests e limits di CPU e memoria per i singoli pod. Il VPA osserva l’utilizzo storico delle risorse di un pod e suggerisce (o applica direttamente) configurazioni ottimali.

Il VPA è particolarmente utile per carichi di lavoro con pattern di utilizzo delle risorse variabili che non beneficiano di uno scaling orizzontale, o per ottimizzare le risorse e ridurre gli sprechi. Può operare in diverse modalità:

  • Off: Suggerisce solo i valori ottimali, non li applica.
  • Initial: Applica i suggerimenti solo all’avvio del pod.
  • Recreate: Termina e ricrea i pod per applicare i nuovi valori.
  • Auto: Regola dinamicamente le risorse senza ricreare il pod (richiede funzionalità beta di Kubernetes).

L’implementazione del VPA è più complessa rispetto all’HPA e richiede un’attenta valutazione, specialmente per la modalità Recreate che comporta downtime temporaneo per il pod.

6. kube-resource-report: Panoramica Cluster in un Comando

Per avere una visione d’insieme dell’utilizzo delle risorse e della configurazione nel tuo cluster, strumenti come kube-resource-report o anche semplici comandi kubectl sono indispensabili. Per un’analisi rapida e senza fronzoli dell’uso attuale delle risorse, puoi usare:

kubectl top pods --all-namespaces --sort-by=cpu

Questo comando ti darà una panoramica immediata dei pod che stanno consumando più CPU, utile per identificare potenziali problemi o pod mal configurati. Per un’analisi più approfondita e report aggregati, tool esterni come kube-resource-report o dashboard di monitoraggio (es. Grafana con Prometheus) sono essenziali per un ambiente di produzione. Leggi anche: Prometheus Alerting: Configurare AlertManager con Notifiche Telegram, Email e PagerDuty (2026)

Errori comuni e troubleshooting

  • OOMKilled frequenti: Indica che i limits di memoria sono troppo bassi o che c’è un memory leak nell’applicazione. Aumentare il limit può risolvere temporaneamente, ma è cruciale indagare la causa del consumo eccessivo.
  • Pod Pending: Spesso significa che le requests di CPU o memoria sono troppo alte e non ci sono nodi con risorse sufficienti per schedulare il pod. Controlla kubectl describe pod per i dettagli.
  • CPU Throttling: Se i limits di CPU sono troppo bassi, l’applicazione potrebbe subire rallentamenti. Monitora l’utilizzo della CPU e aumenta i limits se necessario, ma fai attenzione a non sovra-provisionare.
  • HPA non scala: Verifica che metrics-server sia installato e funzionante (kubectl top pods dovrebbe funzionare). Controlla gli eventi dell’HPA (kubectl describe hpa ) per capire perché non sta scalando.
  • Dimenticare i requests: Questo è un errore comune che porta i pod ad avere QoS BestEffort, rendendoli vulnerabili all’eviction in caso di scarsità di risorse. Usa LimitRange per impostare dei default.

FAQ — Domande Frequenti

Devo sempre impostare sia requests che limits?

Sì, per la maggior parte dei carichi di lavoro in produzione è fortemente consigliato impostare sia requests che limits. Le requests aiutano lo scheduler a posizionare i pod correttamente, mentre i limits prevengono che un singolo pod comprometta l’intero nodo. La loro combinazione garantisce una QoS Guaranteed o Burstable, riducendo il rischio di eviction.

Qual è la differenza pratica tra HPA e VPA?

L’HPA (Horizontal Pod Autoscaler) aumenta o diminuisce il numero di pod (scaling orizzontale) in base al carico. Il VPA (Vertical Pod Autoscaler) aggiusta le risorse (CPU/memoria) di un singolo pod (scaling verticale). L’HPA è ideale per applicazioni stateless e scalabili, mentre il VPA è per ottimizzare l’utilizzo delle risorse di pod singoli o stateful.

Come posso monitorare l’utilizzo delle risorse del mio cluster?

Per un monitoraggio di base, kubectl top nodes e kubectl top pods sono un buon inizio. Per un monitoraggio più avanzato e in produzione, l’integrazione con Prometheus e Grafana è lo standard de facto. Questi strumenti permettono di visualizzare l’utilizzo storico, impostare alert e analizzare trend, essenziali per la pianificazione della capacità.

È possibile che un pod con Guaranteed QoS venga comunque terminato?

Sì, anche un pod Guaranteed può essere terminato, ma è l’ultima risorsa. Questo può accadere in situazioni estreme, come la mancanza di risorse critiche del sistema (es. PIDs, spazio disco) o se il nodo stesso fallisce (es. crash hardware, kernel panic). La classe Guaranteed offre la massima protezione, ma non l’immunità assoluta in caso di fallimenti del nodo.

Conclusioni con takeaway operativi

La gestione delle risorse in Kubernetes non è un optional, ma una pratica fondamentale per la stabilità e l’efficienza degli ambienti di produzione. L’incidente del downtime di 20 minuti per 5 righe di YAML mancanti è un monito potente. Implementare correttamente requests e limits per ogni pod, utilizzare ResourceQuota e LimitRange per imporre policy a livello di namespace, e sfruttare l’autoscaling con HPA e VPA, sono passi cruciali per costruire un’infrastruttura Kubernetes robusta e resiliente. Non lasciare che un pod mal configurato distrugga la tua giornata. Investi tempo nella comprensione e nell’implementazione di queste best practice; pagherà in termini di uptime e tranquillità.

Aggiornato: luglio 2026

Condividi questo articolo:

Scritto da

Rosario Giordano

Rosario Giordano è System Administrator e consulente IT specializzato in cybersecurity e cloud, con oltre 20 anni di esperienza nella gestione di infrastrutture Linux enterprise. Le sue aree di competenza includono hardening di SSH, piattaforme Kubernetes, database PostgreSQL, ambient i virtualizzati VMware e Proxmox, nonché la conformità ai framework di sicurezza NIS2 e ISO 27001.