Come Eseguire Aggiornamenti Rolling a Zero Downtime nei Deployment Kubernetes
Configura gli aggiornamenti rolling di Kubernetes con readiness probe, maxSurge, maxUnavailable e arresto graduale.
Come Eseguire Aggiornamenti Rolling a Zero Downtime nei Deployment Kubernetes
Gli aggiornamenti rolling di Kubernetes possono sostituire i Pod senza un'interruzione visibile, ma solo se il tuo Deployment e la tua applicazione concordano su quando un Pod è pronto e come dovrebbe arrestarsi. La strategia predefinita aiuta, ma non ti salva da readiness probe errate, release incompatibili o richieste in volo perse.
Raggiungere un vero zero downtime, tuttavia, richiede più della semplice configurazione predefinita di Kubernetes. Richiede un'attenta coordinazione tra il manifest del Deployment, gli endpoint di salute dell'applicazione e il processo di terminazione graduale. Questa guida fornisce un approccio completo e passo dopo passo per configurare i Deployment Kubernetes per garantire che gli aggiornamenti dell'applicazione siano senza interruzioni e invisibili per l'utente finale.
Questa guida copre le readiness probe, maxSurge, maxUnavailable e la terminazione graduale in modo che il tuo servizio mantenga la capacità durante un rollout.
Prerequisiti per lo Zero Downtime
Prima di configurare il manifest Kubernetes, l'applicazione sottostante deve aderire a determinati principi per supportare deployment a zero downtime:
- Compatibilità all'indietro dell'Applicazione: Per il breve periodo in cui sia la versione vecchia che quella nuova dell'applicazione sono in esecuzione contemporaneamente, devono essere compatibili con le risorse condivise (database, code, cache).
- Idempotenza: Le operazioni che potrebbero essere gestite da entrambe le versioni devono essere ripetibili senza effetti collaterali negativi.
- Terminazione Graduale: L'applicazione deve essere programmata per riconoscere il segnale
SIGTERMinviato da Kubernetes e interrompere gradualmente l'accettazione di nuove connessioni, completando le richieste in volo prima di uscire.
Comprendere la Strategia di Aggiornamento Rolling di Kubernetes
I Deployment Kubernetes utilizzano per impostazione predefinita la strategia RollingUpdate. Questo metodo garantisce che la vecchia versione dell'applicazione non venga completamente rimossa prima che la nuova versione sia operativa, gestendo la transizione utilizzando due parametri principali:
| Parametro | Descrizione | Impatto sullo Zero Downtime |
|---|---|---|
maxSurge |
Definisce il numero massimo di Pod che possono essere creati oltre il numero desiderato di repliche. Può essere un numero assoluto o una percentuale (default: 25%). | Controlla la velocità del rollout e garantisce un aumento temporaneo della capacità. |
maxUnavailable |
Definisce il numero massimo di Pod che possono essere non disponibili durante l'aggiornamento. Può essere un numero assoluto o una percentuale (default: 25%). | Cruciale per lo zero downtime. Impostarlo a 0% significa che nessun Pod in servizio viene terminato finché i nuovi Pod non sono completamente Ready. |
Strategia Consigliata per lo Zero Downtime
Per la massima disponibilità, la configurazione migliore è spesso quella di garantire zero perdita di capacità durante il downtime:
maxUnavailable: 0(Garantisce che la capacità non scenda mai).maxSurge: 1o25%(Permette alla capacità di superare brevemente il target, assicurando che un nuovo Pod sia pronto prima che uno vecchio venga ucciso).
Passo 1: Implementare le Readiness Probe
La Readiness Probe è il meccanismo più importante per garantire aggiornamenti a zero downtime. Kubernetes si basa su questa sonda per determinare se un nuovo Pod è pronto a ricevere traffico utente e se un vecchio Pod sta ancora servendo attivamente il traffico.
Liveness vs. Readiness
- Liveness Probe: Dice a Kubernetes se il contenitore è sano e funzionale. Se fallisce, il contenitore viene riavviato.
- Readiness Probe: Dice a Kubernetes se il contenitore è pronto per servire le richieste. Se fallisce, il Pod viene rimosso dagli endpoint del Service associato, deviando il traffico lontano da esso fino a quando non diventa pronto.
Per gli aggiornamenti rolling, la Readiness Probe viene utilizzata per controllare la transizione. Kubernetes non procederà a terminare un vecchio Pod finché un Pod appena creato non supera con successo il suo controllo di readiness.
# estratto deployment.yaml
spec:
containers:
- name: my-app
image: myregistry/my-app:v2.0
ports:
- containerPort: 8080
# --- Configurazione Readiness Probe ---
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 15 # Tempo di attesa prima del primo tentativo di sonda
periodSeconds: 5 # Ogni quanto eseguire il controllo
timeoutSeconds: 3
failureThreshold: 3 # Numero di fallimenti consecutivi per contrassegnare il Pod come non pronto
# --- Configurazione Liveness Probe (Controllo di Salute Standard) ---
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
Suggerimento: Assicurati che l'endpoint
/health/readydella tua applicazione restituisca un codice di successo (HTTP 200-299) solo quando l'inizializzazione, le connessioni al database e altre dipendenze esterne sono completamente operative.
Passo 2: Configurare la Strategia di Deployment
Per imporre un vero zero downtime, configuriamo esplicitamente la strategia di aggiornamento rolling per prevenire qualsiasi calo nel numero di repliche disponibili.
In questa configurazione, Kubernetes creerà prima un nuovo Pod (maxSurge: 1). Una volta che il nuovo Pod supera la sua readiness probe, solo allora Kubernetes terminerà un vecchio Pod. Poiché maxUnavailable è 0, la capacità del servizio non scende mai al di sotto del numero di repliche target.
# estratto deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-web-deployment
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
# Garantisce che la capacità non scenda mai al di sotto del numero di repliche desiderato (4)
maxUnavailable: 0
# Permette la creazione di un Pod extra durante il rollout
maxSurge: 1
template:
# ... specifica del contenitore ...
Passo 3: Garantire la Terminazione Graduale
Anche con robuste readiness probe, se l'applicazione si arresta istantaneamente al ricevimento del segnale di terminazione, rischia di perdere le richieste in volo.
Kubernetes segue una sequenza di terminazione specifica:
- Il Pod viene contrassegnato come Terminating.
- Il Pod viene rimosso dagli endpoint del Service (il traffico smette di essere instradato verso di esso).
- Viene eseguito il pre-stop hook (se definito).
- Il contenitore riceve il segnale
SIGTERM. - Kubernetes attende per la durata definita da
terminationGracePeriodSeconds(default: 30 secondi). - Se il contenitore è ancora in esecuzione, riceve un
SIGKILLnon negoziabile.
Per garantire un arresto graduale, l'applicazione deve gestire SIGTERM e terminationGracePeriodSeconds deve essere abbastanza lungo per consentire all'applicazione di completare le richieste esistenti.
# estratto deployment.yaml, all'interno della specifica del Pod template
spec:
terminationGracePeriodSeconds: 45 # Impostazione a livello di Pod
containers:
- name: my-app
image: myregistry/my-app:v2.0
lifecycle:
preStop:
exec:
# Dà tempo agli aggiornamenti degli endpoint e ai bilanciatori di carico esterni per drenare.
command: ["/bin/sh", "-c", "sleep 10"]
Buona Pratica: La tua applicazione dovrebbe smettere di accettare nuovo lavoro quando riceve
SIGTERM, quindi completare le richieste in volo prima di uscire. UnterminationGracePeriodSecondsleggermente più lungo, come 45 o 60 secondi, aiuta a prevenire kill forzati per richieste più lente.
Passo 4: Eseguire e Monitorare l'Aggiornamento
Una volta che il manifest del Deployment include la strategia ottimizzata e sonde robuste, eseguire l'aggiornamento è semplice.
Aggiornare il Tag dell'Immagine: Modifica il manifest del deployment per riflettere la nuova versione dell'immagine (es.,
v2.0av2.1).Applicare la Configurazione:
kubectl apply -f deployment.yamlIn alternativa, puoi modificare direttamente l'immagine:
kubectl set image deployment/my-web-deployment my-app=myregistry/my-app:v2.1Monitorare lo Stato del Rollout: Osserva Kubernetes progredire attraverso le fasi, verificando che il numero di Pod pronti non scenda mai al di sotto del numero desiderato.
kubectl rollout status deployment/my-web-deploymentVerificare la Disponibilità dei Pod: Osserva lo stato dei Pod per confermare che i vecchi Pod (v2.0) vengano terminati gradualmente solo dopo che i nuovi Pod (v2.1) sono completamente pronti.
kubectl get pods -l app=my-web-deployment -w
Considerazioni Avanzate
Utilizzare i Pod Disruption Budget (PDB)
Mentre una strategia di deployment gestisce i rollout, un Pod Disruption Budget (PDB) limita le interruzioni volontarie come i drenaggi dei nodi e alcune operazioni di manutenzione del cluster. Non previene ogni guasto non pianificato, ma fornisce a Kubernetes e agli strumenti di automazione un obiettivo di disponibilità minima da rispettare.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
spec:
minAvailable: 75% # Garantisce che almeno il 75% delle repliche sia sempre disponibile
selector:
matchLabels:
app: my-web-deployment
L'Importanza del Ritardo Iniziale
Se la tua applicazione richiede tempo per riscaldarsi, regola initialDelaySeconds, periodSeconds e failureThreshold in modo che la readiness rifletta il comportamento di avvio reale. Una readiness probe che fallisce mantiene il Pod fuori dagli endpoint del Service; una liveness probe che fallisce è ciò che può riavviare il contenitore e creare un ciclo di crash.
Eseguire il Rollout in Sicurezza
Raggiungere aggiornamenti rolling a zero downtime in Kubernetes è una combinazione di una configurazione robusta della piattaforma e uno sviluppo disciplinato dell'applicazione. Sfruttando correttamente le Readiness Probe per segnalare lo stato operativo, ottimizzando la strategia di Deployment (maxUnavailable: 0) per mantenere la capacità e implementando gestori di terminazione graduale, puoi garantire che gli aggiornamenti dell'applicazione vengano eseguiti in modo affidabile senza interrompere il servizio per i tuoi utenti. Testa sempre il tuo processo di aggiornamento accuratamente in un ambiente di staging per convalidare il periodo di grazia di terminazione e la logica delle sonde.