Introduzione
Gli aggiornamenti continui sono una parte importante del ciclo di vita di un'app moderna, con gli utenti che si aspettano costantemente nuove funzionalità e zero tempi di inattività. Mentre Kubernetes utilizzava i controller di replica per abilitare questa funzionalità in passato, le versioni più recenti consigliano di utilizzare le distribuzioni.
Questo tutorial mostra come eseguire aggiornamenti in sequenza utilizzando Kubernetes Deployments. Questo metodo ti consente di aggiornare rapidamente le tue app e ottenere zero tempi di inattività garantendo al contempo il supporto per il rollback.
Prerequisiti
- Un cluster Kubernetes
- Accesso a una finestra del terminale
- Lo strumento da riga di comando kubectl
Abilita aggiornamenti continui
Le distribuzioni Kubernetes fungono da wrapper attorno ai ReplicaSet, che sono i controller Kubernetes responsabili della gestione dei pod. Le distribuzioni forniscono funzionalità aggiuntive ai ReplicaSet:eseguono controlli dello stato, aggiornamenti in sequenza e rollback.
1. Innanzitutto, crea un yaml file con le specifiche di distribuzione utilizzando un editor di testo, come Nano:
nano nginx-test.yaml
Il file di esempio seguente contiene le dichiarazioni di base necessarie per una distribuzione Kubernetes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 4
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
2. Salva ed esci dal file.
3. Quindi, crea la distribuzione utilizzando kubectl create
comando e yaml file che hai appena creato:
kubectl create -f nginx-test.yaml
4. Controlla la distribuzione:
kubectl get deployment
L'output dovrebbe confermare che la distribuzione è pronta:
4. Quindi, controlla i ReplicaSet eseguendo il comando:
kubectl get rs
Il file di esempio ha specificato quattro repliche, che vengono visualizzate tutte come pronte:
5. Infine, controlla se i pod sono attivi:
kubectl get pod
L'output mostra i pod come pronti e in esecuzione:
Garantire zero tempi di inattività
Per configurare gli aggiornamenti in sequenza senza tempi di inattività, è necessario specificare la strategia di aggiornamento.
1. Aggiungi la seguente dichiarazione alla distribuzione yaml file sotto le spec
categoria:
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
minReadySeconds
dice a Kubernetes quanto tempo deve attendere prima di creare il pod successivo. Questa proprietà garantisce che tutti i pod dell'applicazione siano pronti durante l'aggiornamento.maxSurge
specifica il numero massimo (o percentuale) di pod al di sopra del numero specificato di repliche. Nell'esempio sopra, il numero massimo di pod sarà 5 da 4 le repliche sono specificate in yaml file.maxUnavailable
dichiara il numero massimo (o percentuale) di pod non disponibili durante l'aggiornamento. SemaxSurge
è impostato su 0 , questo campo non può essere 0 .
Aggiunta della specifica precedente alla distribuzione yaml è sufficiente per iniziare a eseguire gli aggiornamenti in sequenza di Kubernetes. Tuttavia, non garantisce zero tempi di inattività. Kubernetes non è in grado di dire quando un nuovo pod è pronto:elimina il vecchio pod non appena viene creato quello nuovo. Questo problema causa tempi di inattività finché il nuovo pod non è in grado di accettare le richieste.
Per risolvere questo problema, Kubernetes presenta il concetto di Readiness Probes . Le sonde controllano lo stato dei pod e consentono agli aggiornamenti in sequenza di procedere solo quando tutti i contenitori in un pod sono pronti. I pod sono considerati pronti quando il probe di disponibilità ha esito positivo e dopo il tempo specificato in minReadySeconds
è passato.
2. Per impostare Readiness Probes, aggiungi le seguenti righe a spec.template.spec
categoria nel file di distribuzione:
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
initialDelaySeconds
specifica per quanto tempo il probe deve attendere per l'avvio dopo l'avvio del contenitore.periodSeconds
è il tempo tra due sonde. L'impostazione predefinita è 10 secondi, mentre il valore minimo è 1 secondo.successThreshold
è il numero minimo di sonde consecutive riuscite dopo una non riuscita affinché l'intero processo sia considerato riuscito. I valori predefinito e minimo sono entrambi 1 .
L'intero file di distribuzione configurato correttamente per gli aggiornamenti in sequenza dovrebbe essere simile al seguente:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 4
selector:
matchLabels:
app: nginx
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.0
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
3. Salvare il file ed uscire.
4. Quindi, usa kubectl apply
per applicare le modifiche:
kubectl apply -f nginx-text.yaml --record
Il --record
flag servirà a uno scopo nel processo di rollback.
L'output mostra che la distribuzione è stata configurata correttamente.
Esegui aggiornamento continuo
Esistono tre modi per eseguire gli aggiornamenti in sequenza.
Ad esempio, per modificare l'immagine dell'app:
Opzione 1:puoi utilizzare kubectl set
per eseguire l'azione sulla riga di comando:
kubectl set image deployment nginx-deployment nginx=nginx:1.14.2 --record
Opzione 2:in alternativa, modifica la versione dell'immagine in spec.templates.spec.containers
sezione di yaml file. Quindi, usa kubectl replace
per eseguire l'aggiornamento:
kubectl replace -f nginx-test.yaml
Opzione 3:puoi anche utilizzare kubectl edit
per modificare direttamente la distribuzione:
kubectl edit deployment nginx-deployment --record
Apporta le modifiche necessarie nell'editor che si apre:
Le modifiche vengono applicate alla chiusura dell'editor.
Controlla lo stato di implementazione
Verifica lo stato di implementazione della distribuzione utilizzando la seguente sintassi:
kubectl rollout status deployment nginx-deployment
L'output conferma il successo del rollout:
Sospendi e riprendi aggiornamento in sequenza
Metti in pausa e riprendi gli aggiornamenti in sequenza con il rispettivo kubectl rollout
comandi.
Per sospendere l'aggiornamento, esegui:
kubectl rollout pause deployment nginx-deployment
Per riprendere l'aggiornamento, esegui:
kubectl rollout resume deployment nginx-deployment
Pianifica i contenitori per la distribuzione
Usa le proprietà di affinità e anti-affinità per controllare su quali nodi Kubernetes pianifica pod specifici nella tua distribuzione.
Affinità Pod
Esistono due tipi di affinità attualmente disponibile in Kubernetes:
requiredDuringSchedulingIgnoredDuringExecution
dice a Kubernetes di eseguire i pod solo su nodi che soddisfano determinati criteri, come un tipo di processore specifico.preferredDuringSchedulingIgnoredDuringExecution
consente di eseguire i pod altrove, se e solo se nessun nodo soddisfa determinati criteri.
Queste proprietà sono elencate in PodSpec file. Ad esempio, un pod può essere specificato come segue:
apiVersion: v1
kind: Pod
metadata:
name: affinity-test
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/test-name
operator: In
values:
- test1
- test2
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: example-node-label-key
operator: In
values:
- example-node-label-value
containers:
- name: affinity-test
image: k8s.gcr.io/pause:2.0
Il file sopra indica a Kubernetes di eseguire il pod solo su un nodo con un'etichetta la cui chiave è kubernetes.io/test-name
e il cui valore è test1
o test2
. Inoltre, Kubernetes preferirà i nodi la cui chiave è example-node-label-key
, con il example-node-label-value
valore.
Pod Anti-Affinità
Anti-affinità pod è utile se non si desidera che tutti i pod vengano eseguiti sullo stesso nodo. Funziona in modo simile all'affinità, con gli stessi due tipi disponibili:requiredDuringSchedulingIgnoredDuringExecution
e preferredDuringSchedulingIgnoredDuringExecution
.
L'esempio seguente specifica una regola di anti-affinità che dice a Kubernetes di evitare preferibilmente di programmare i pod dell'app "test" su nodi che hanno già i pod "test":
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- test
topologyKey: Kubernetes.io/hostname
Modifiche al rollback
Se qualcosa va storto con il processo di aggiornamento, puoi ripristinare le modifiche e ripristinare una versione precedente dell'app. A tale scopo, utilizza il seguente kubectl rollout
comando:
kubectl rollout history deployment nginx-deployment
L'output elenca le revisioni disponibili, create aggiungendo il --record
flag durante l'esecuzione di un aggiornamento:
Scegli la revisione che desideri e digita il seguente comando per ripristinare le modifiche:
kubectl rollout undo deployment nginx-deployment --to-revision=1
Il comando precedente torna alla revisione 1 e produce il seguente output: