
Il processo di aggiornamento per il tuo cluster Kubernetes
Ad un certo punto nell'utilizzo di un cluster Kubernetes, si presenta la necessità di aggiornare i nodi in funzione. Questo può includere aggiornamenti dei pacchetti, aggiornamenti del kernel o il deployment di nuove immagini di macchine virtuali. Nella terminologia di Kubernetes, questo si chiama .
Questo post fa parte di un ciclo di 4 articoli:
- Questo post.
- Terminazione corretta dei pod in un cluster Kubernetes
- Terminazione ritardata di un pod durante la sua eliminazione
- Come evitare interruzioni nel funzionamento del cluster Kubernetes con i PodDisruptionBudgets
(Nota: le traduzioni degli altri articoli del ciclo arriveranno a breve)
In questo articolo descriveremo tutti gli strumenti forniti da Kubernetes per ottenere un tempo di inattività nullo per i nodi del tuo cluster.
Definizione del problema
Inizialmente utilizzeremo un approccio naive, identificando problemi e valutando i potenziali rischi di questo approccio, accumulando conoscenze per risolvere ciascuno dei problemi che incontreremo durante tutto il ciclo. Il risultato sarà una configurazione che utilizza lifecycle hooks, readiness probes e Pod disruption budgets per raggiungere il nostro obiettivo di tempo di inattività nullo.
Per iniziare il nostro percorso, prendiamo un esempio concreto. Supponiamo di avere un cluster Kubernetes composto da due nodi, su cui è in esecuzione un'applicazione con due pod, situati dietro Service:

Iniziamo con due pod di Nginx e un servizio in esecuzione sui nostri due nodi del cluster Kubernetes.
Vogliamo aggiornare la versione del kernel dei due nodi operativi nel nostro cluster. Come possiamo farlo? Una soluzione semplice sarebbe quella di avviare nuovi nodi con una configurazione aggiornata e poi spegnere i vecchi nodi, avviando contemporaneamente i nuovi. Anche se questo funziona, ci sarebbero diversi problemi con questo approccio:
- Quando spegnerai i vecchi nodi, i pod in esecuzione su di essi verranno anch'essi spenti. Cosa succede se i pod devono essere liberati per uno spegnimento corretto? Il sistema di virtualizzazione che stai utilizzando potrebbe non attendere il completamento del processo di pulizia.
- E se scollegassi tutti i nodi contemporaneamente? Avrai un’interruzione significativa finché i pod vengono spostati sui nuovi nodi.
Abbiamo bisogno di un modo per migrare correttamente i pod dai vecchi nodi, assicurandoci che nessuno dei nostri processi di lavoro sia in esecuzione mentre apportiamo modifiche al nodo. Oppure, quando facciamo una sostituzione completa del cluster, come nell'esempio (cioè sostituendo le immagini delle VM), vogliamo trasferire le applicazioni funzionanti dai vecchi nodi ai nuovi. In entrambi i casi, vogliamo impedire la programmazione di nuovi pod sui vecchi nodi e poi espellere tutti i pod in esecuzione. Per raggiungere questi obiettivi, possiamo utilizzare il comando kubectl drain.
Espelli tutti i pod dal nodo
L'operazione di drain consente di espellere tutti i pod da un nodo. Durante l'esecuzione del drain, il nodo viene contrassegnato come non schedulabile (flag NoSchedule). Questo previene l'emergere di nuovi pod su di esso. Poi il drain inizia a espellere i pod dal nodo, terminando i contenitori attualmente in esecuzione sul nodo inviando il segnale TERM ai contenitori nel pod.
Sebbene kubectl drain Anche se il sistema gestisce bene l'espulsione dei pod, ci sono ancora due fattori che possono causare un fallimento durante l'operazione di drain:
- La tua applicazione deve essere in grado di terminare correttamente al ricevimento del segnale. Quando i pod vengono espulsi, Kubernetes invia il segnale
TERMai contenitori e attende la loro fermata per un tempo stabilito, dopodiché, se non si sono fermati, li forza a terminare. In ogni caso, se il tuo contenitore non interpreta il segnale correttamente, potresti comunque spegnere i pod in modo errato se si trovano in esecuzione in quel momento (ad esempio, un'operazione di transazione nel database).TERMPerdi tutti i pod che contengono la tua applicazione. Potrebbe non essere disponibile al momento dell'avvio di nuovi contenitori sui nuovi nodi o, se i tuoi pod sono distribuiti senza controllori, potrebbero non riavviarsi affatto. - Evitare l’inattività
Per ridurre al minimo il tempo di inattività derivante da interruzioni volontarie, come quelle causate dall'operazione di drain di un nodo, Kubernetes offre le seguenti opzioni di gestione dei fallimenti:
Terminazione graduale
--- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.15 ports: - containerPort: 80 --- kind: Service apiVersion: v1 metadata: name: nginx-service spec: selector: app: nginx ports: - protocol: TCP targetPort: 80 port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.15
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
targetPort: 80
port: 80Questa configurazione è un esempio minimo Deployment, che gestisce i pod nginx in un cluster. Inoltre, la configurazione descrive una risorsa Service, che può essere utilizzata per accedere ai pod nginx nel cluster.
Nel corso del ciclo, espanderemo iterativamente questa configurazione fino a includere tutte le funzionalità offerte da Kubernetes per ridurre al minimo i tempi di inattività.
Per ottenere una versione completamente implementata e testata degli aggiornamenti del cluster Kubernetes per zero tempi di inattività su AWS e altre risorse, visita .
Leggi anche altri articoli nel nostro blog:
Fonte: habr.com
