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
requestsper 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
limitdi memoria, verrà terminato (OOMKilled – Out Of Memory Killed) dal kubelet. Se supera illimitdi CPU, la sua esecuzione verrà throttlata, ma non verrà terminato. Lelimitssono 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 è
Guaranteedse lerequestsdi CPU e memoria sono uguali ailimitsper 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 è
Burstablese ha almeno unarequestdi CPU o memoria configurata, e lerequestssono inferiori ailimits(o ilimitsnon sono specificati). Questi pod hanno una priorità intermedia e possono essere terminati prima dei podGuaranteed. - BestEffort: Un pod è
BestEffortse nessuno dei suoi container specificarequestsolimitsper 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.
- LimitRange: Definisce i
defaulte imassimirequestselimitsper i pod e i container all’interno di un namespace. Se un pod non specificarequestsolimits,LimitRangepuò iniettare i valori di default. Questo evita che i developer dimentichino di configurare le risorse. Leggi anche: Helm Kubernetes: Deploy e Gestione Applicazioni con Package Manager (2026)
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
requestselimitsper 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
limitsdi memoria sono troppo bassi o che c’è un memory leak nell’applicazione. Aumentare illimitpuò risolvere temporaneamente, ma è cruciale indagare la causa del consumo eccessivo. - Pod Pending: Spesso significa che le
requestsdi CPU o memoria sono troppo alte e non ci sono nodi con risorse sufficienti per schedulare il pod. Controllakubectl describe podper i dettagli. - CPU Throttling: Se i
limitsdi CPU sono troppo bassi, l’applicazione potrebbe subire rallentamenti. Monitora l’utilizzo della CPU e aumenta ilimitsse necessario, ma fai attenzione a non sovra-provisionare. - HPA non scala: Verifica che
metrics-serversia installato e funzionante (kubectl top podsdovrebbe 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 QoSBestEffort, rendendoli vulnerabili all’eviction in caso di scarsità di risorse. UsaLimitRangeper 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