Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Basta over-provisioning per l'avvio: il nuovo CPU Startup Boost di GKE

Questa pagina è disponibile anche in English, Deutsch, Español, Français, 日本語 e Português.

By Chimbu ChinnaduraiJul 27, 20267 min read
Chimbu Chinnadurai

About Chimbu Chinnadurai

I've probably debugged a Kubernetes issue in more time zones than I care to count. Based in London, I help engineering teams across EMEA get their clusters to behave — and actually understand why they misbehaved in the first place.

I write, speak, and guest on podcasts about all things cloud-native. Away from the terminal: I enjoy cooking almost as much as simplifying overly complex systems.

My personal page

Se hai mai eseguito una JVM, un'app Spring Boot o qualsiasi applicazione basata su un framework pesante su Kubernetes, sai già come va a finire. Una volta che il container è caldo, tutto fila liscio. La latenza si stabilizza, l'uso della CPU cala e l'app gira senza problemi. Ma nei primi secondi, a volte decine di secondi, dopo l'avvio del container, è un workload completamente diverso. Caricamento delle classi, warm-up del JIT, grafi di dependency injection e inizializzazione dei connection pool. Sono tutte operazioni affamate di CPU, tutte insieme, e finiscono quasi con la stessa rapidità con cui sono iniziate.

Kubernetes non distingue tra "steady-state" e "cold-start". Qualunque CPU request tu imposti per il container, quella rimane per l'intera vita del Pod.

PerfectScale™ for Kubernetes

Ready to optimize?

Get your free Kubernetes savings analysis

Il compromesso: velocità di avvio vs. spreco a riposo

Ogni team che esegue workloads pesanti e sensibili alla latenza su Kubernetes è costretto a scegliere tra due compromessi frustranti:

Dimensionare per l'avvio e pagarlo per sempre. Imposti la CPU request abbastanza alta da completare rapidamente l'inizializzazione, anche se l'app ha bisogno di pochissima CPU una volta calda. Quella request resta lì 24 ore su 24. È ciò che lo scheduler usa per collocare il Pod, ciò che il cluster autoscaler usa per decidere se aggiungere nodi ed è ciò che ti viene fatturato. Su qualche centinaio di repliche, il compromesso tra avvio più rapido e spreco continuo si accumula in fretta.

Dimensionare per lo steady-state e soffrire all'avvio. Imposti la request in linea con l'utilizzo effettivo a runtime e accetti che ogni riavvio, ogni rolling deployment, ogni upgrade dei nodi comporti una lenta marcia verso la readiness. Sotto CPU throttling, un warm-up della JVM che dovrebbe richiedere 5 secondi può allungarsi a 30 o più. Questo significa rollout più lenti, scale-out più lento durante gli eventi HPA e potenziali picchi di latenza per gli utenti.

Nessuna delle due opzioni è davvero accettabile. Il CPU startup boost nasce per colmare questo divario.

Cosa risolve davvero il CPU startup boost

Il CPU startup boost è una nuova funzionalità del Vertical Pod Autoscaler (VPA) di GKE, attualmente in Preview. Permette di aumentare temporaneamente la CPU request di un container durante l'inizializzazione del Pod, per poi riportarla automaticamente al valore di base senza riavviare il container.

I runtime affamati di risorse (Java, Node.js e Python con import pesanti) ottengono il margine di CPU di cui hanno bisogno solo quando serve, cioè durante l'inizializzazione. La request di base può così riflettere l'utilizzo reale in steady-state anziché un compromesso gonfiato per i primi secondi di vita del Pod. Poiché il ridimensionamento dal valore boostato a quello di base usa l'in-place Pod resize (IPPR) di Kubernetes anziché un'eviction con ricreazione del Pod, il container continua a girare per tutto il tempo.

Tutto questo funziona in parallelo al compito abituale del VPA, ovvero raccomandare e applicare il dimensionamento delle risorse a lungo termine. Lo startup boost, in fondo, non è che un override di breve durata applicato sopra il valore di base che il VPA (o tu stesso) ha già stabilito.

Come funziona e come configurarlo

Guida completa qui: Accelerate application startup with CPU startup boost.

Il CPU startup boost si definisce aggiungendo un blocco startupBoost all'oggetto VerticalPodAutoscaler. Puoi applicarlo a livello di Pod, così ogni container riceve lo stesso boost, oppure a livello di container, per indirizzare container specifici o escluderne alcuni da un boost applicato all'intero Pod.

Si attiva solo alla creazione del Pod. Se un container si riavvia in un secondo momento, ad esempio dopo un OOMKill mentre il Pod resta in vita, il boost non viene riapplicato. L'admission webhook che inietta il boost viene eseguito solo all'admission iniziale del Pod.

Il tipo di boost può essere un moltiplicatore o una quantità fissa. type: "Factor" scala la CPU request di base per un moltiplicatore (factor: 2 la raddoppia); type: "Quantity" aggiunge una quantità fissa di CPU al valore di base.

Funziona insieme alle update modes del VPA, non al loro posto. Eseguilo con updateMode: "Off" se vuoi solo il comportamento di boost e nient'altro, oppure abbinalo a updateMode: "InPlaceOrRecreate" se vuoi che il VPA continui anche ad adeguare le risorse in base all'utilizzo effettivo.

Per configurare un boost a livello di Pod, usa una delle seguenti opzioni.

Boost a livello di Pod, con attuazione del VPA disattivata

Usa questa opzione quando vuoi il boost e nient'altro: il VPA non applicherà nessun'altra raccomandazione sulle risorse.

apiVersion: "autoscaling.k8s.io/v1"
kind: VerticalPodAutoscaler
metadata:
name: example-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: example
updatePolicy:
updateMode: "Off"
startupBoost:
cpu:
type: "Factor"
factor: 2
durationSeconds: 10

Ogni container del Pod riceve il doppio della sua CPU request di base per i primi 10 secondi dopo che il Pod raggiunge lo stato Ready, dopodiché GKE la riporta al valore di base in place.

Boost a livello di Pod, con gestione VPA continua

Usa questa opzione quando vuoi sia lo startup boost sia, successivamente, un right-sizing continuo delle risorse in place.

apiVersion: "autoscaling.k8s.io/v1"
kind: VerticalPodAutoscaler
metadata:
name: example-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: example
updatePolicy:
updateMode: "InPlaceOrRecreate"
startupBoost:
cpu:
type: "Factor"
factor: 2
durationSeconds: 10

Stesso comportamento di boost, ma con updateMode: "InPlaceOrRecreate" il VPA continua a raccomandare e applicare modifiche alle risorse per tutta la vita del Pod, tentando prima il resize in place e ripiegando sulla ricreazione se necessario.

Boost a livello di container, mirato a un singolo container

Utile quando un Deployment include un sidecar o un container di servizio che non ha bisogno del picco di CPU all'avvio. Limiti il boost al solo container che ne ha bisogno tramite resourcePolicy.containerPolicies.

apiVersion: "autoscaling.k8s.io/v1"
kind: VerticalPodAutoscaler
metadata:
name: example-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: example
updatePolicy:
updateMode: "Off"
resourcePolicy:
containerPolicies:
- containerName: "boosted-container-name"
mode: "Off"
startupBoost:
cpu:
type: "Quantity"
quantity: "2"

Qui boosted-container-name riceve 2 vCPU extra oltre alla sua request di base durante l'avvio: una quantità fissa anziché un moltiplicatore.

Escludere un container da un boost a livello di Pod

Il caso inverso: è impostato un boost a livello di Pod, ma uno dei container non deve essere boostato insieme al resto.

apiVersion: "autoscaling.k8s.io/v1"
kind: VerticalPodAutoscaler
metadata:
name: example-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: example
updatePolicy:
updateMode: "InPlaceOrRecreate"
startupBoost:
cpu:
type: "Factor"
factor: 2
resourcePolicy:
containerPolicies:
- containerName: "disable-cpu-boost-for-this-container"
startupBoost:
cpu:
type: "Factor"
factor: 1

Il boost a livello di Pod applica di default un fattore 2x a tutti i container, ma la policy del container lo sovrascrive con un fattore 1 per il container indicato.

Your cloud bill shouldn't be a mystery

Optimization, automation, expertise. In one platform.

Altre cose da sapere prima di attivarlo

Prima di usare il CPU startup boost devono essere soddisfatti alcuni requisiti operativi.

Requisiti. Serve GKE 1.36.0-gke.4447000 o versione successiva, su Standard o Autopilot. Il VPA deve essere abilitato: è attivo di default su Autopilot, mentre su Standard va abilitato esplicitamente. Il workload deve inoltre essere gestito da un controller (Deployment, StatefulSet e così via); i Pod standalone non sono supportati. Elenco completo qui: CPU startup boost requirements.

Interazioni con l'HPA. Se usi anche l'Horizontal Pod Autoscaler, definisci una readinessProbe e imposta durationSeconds: 0 sul boost. Altrimenti l'HPA può interpretare il picco temporaneo di CPU come carico reale e fare scale-out prematuramente. Vedi Interactions with horizontal Pod autoscaling.

Interazioni con il cluster autoscaler su Standard. Uno startup boost può innescare uno scale-up dei nodi per fare spazio alla request boostata. Quando il boost scade e il nodo appare sottoutilizzato, questo può innescare uno scale-down con conseguente eviction del Pod: un loop. GKE raccomanda esplicitamente di usare Autopilot se vuoi evitare fin da subito questi loop di deframmentazione. Vedi Cluster autoscaler and eviction loops.

Limiti di capacità dei nodi. Sui cluster Standard, se non c'è spazio per l'intera request boostata, GKE la limita a quanto effettivamente entra nel nodo.

Verifica. Conferma che un boost sia stato applicato controllando la presenza di un'annotazione vpaCpuStartupBoost/<container-name> sul Pod, e verifica che il boost sia stato rimosso cercando un evento InPlaceResizedByVPA (kubectl get events --field-selector reason=InPlaceResizedByVPA). Passaggi completi: Verify CPU startup boost.

Conclusione

Il CPU startup boost colma una lacuna concreta nel modo in cui Kubernetes gestisce il dimensionamento delle risorse. Disaccoppia "ciò di cui la mia app ha bisogno per avviarsi in fretta" da "ciò di cui ha bisogno una volta in esecuzione", una distinzione che finora significava gonfiare per sempre le request di base oppure convivere con avvii lenti e soggetti a throttling. Ora ottieni sia un avvio rapido sia un footprint snello in steady-state, applicato automaticamente e rimosso in place senza interrompere il container.

È ancora una funzionalità in Preview, quindi valgono le solite cautele: valutala prima in un ambiente non di produzione e presta molta attenzione alle interazioni tra HPA e cluster autoscaler prima di adottarla su larga scala.

Il right-sizing oltre la finestra di avvio

Il CPU startup boost risolve il picco iniziale di boot, ma dipende comunque da un valore di base steady-state accurato. Su una flotta di grandi dimensioni, mantenere accurate nel tempo le request di base di CPU e memoria è un problema costante.

È qui che entra in gioco PerfectScale by DoiT. PerfectScale monitora l'utilizzo reale per fare right-sizing continuo delle request di base dei pod. Usa l'in-place Pod resizing per adeguare le risorse senza eviction né riavvii, lavorando insieme agli autoscaler che già utilizzi (come Cluster Autoscaler o Karpenter).

Se lo startup boost ti garantisce un cold start rapido e senza interruzioni, PerfectScale è ciò che impedisce al resto del ciclo di vita del Pod di scivolare di nuovo verso l'over- o l'under-provisioning.

Prenota una demo per saperne di più su PerfectScale by DoiT.