Canary Deployment in Kubernetes #1: Gitlab CI

Utilizzeremo Gitlab CI e GitOps manuale per implementare e utilizzare il Canary deployment in Kubernetes.

Canary Deployment in Kubernetes #1: Gitlab CI

Articoli di questo ciclo:

Eseguiremo il Canary deploy manualmente tramite GitOps e creando/modificando le risorse principali di Kubernetes. Questo articolo è principalmente destinato a familiarizzare con il funzionamento del Canary deployment in Kubernetes, poiché ci sono modi più efficaci di automazione che esploreremo nei prossimi articoli.


Canary Deployment in Kubernetes #1: Gitlab CI

https://www.norberteder.com/canary-deployment/

Distribuzione Canary

Con la strategia di aggiornamento Canary, le modifiche vengono inizialmente applicate solo a una parte degli utenti. Attraverso il monitoraggio, i dati dei log, i test manuali o altri canali di feedback, la versione viene testata prima della sua applicazione a tutti gli utenti.

Kubernetes Deployment (rolling update)

La strategia predefinita per il Kubernetes Deployment è il rolling-update, dove viene avviato un numero definito di pod con nuove versioni delle immagini. Se vengono creati senza problemi, i pod con le vecchie versioni delle immagini si fermano e nuovi pod vengono creati in parallelo.

GitOps

Utilizziamo GitOps in questo esempio, poiché:

  • utilizziamo Git come unica fonte di verità
  • utilizziamo Git Operations per costruire e distribuire (nessun comando oltre a git tag/merge necessario)

Esempio

Adottiamo una buona pratica: avere un repository per il codice delle applicazioni e uno per l'infrastruttura.

Repository per le applicazioni

Si tratta di una semplice API in Python+Flask, che restituisce una risposta in formato JSON. Creeremo il pacchetto tramite GitlabCI e pubblicheremo il risultato nel Gitlab Registry. Nel registro abbiamo due diverse versioni di rilascio:

  • wuestkamp/k8s-deployment-example-app:v1
  • wuestkamp/k8s-deployment-example-app:v2

L'unica differenza tra di esse è la modifica del file JSON restituito. Utilizziamo questa applicazione per visualizzare in modo semplice con quale versione stiamo interagendo.

Repository infrastrutturale

In questo repository faremo il deploy tramite GitlabCI in Kubernetes. .gitlab-ci.yml si presenta come segue:

image: traherom/kustomize-docker

before_script:
   - printenv
   - kubectl version

stages:
 - deploy

deploy test:
   stage: deploy
   before_script:
     - echo $KUBECONFIG
   script:
     - kubectl get all
     - kubectl apply -f i/k8s

   only:
     - master

Per avviarlo da solo avrete bisogno di un cluster, potete utilizzare Gcloud:

gcloud container clusters create canary --num-nodes 3 --zone europe-west3-b

gcloud compute firewall-rules create incoming-80 --allow tcp:80

Dovete fare un fork https://gitlab.com/wuestkamp/k8s-deployment-example-canary-infrastructure e creare una variabile KUBECONFIG in GitlabCI, che conterrà la configurazione per l'accesso kubectl al vostro cluster.

Per informazioni su come ottenere le credenziali per il cluster (Gcloud), puoi leggere qui.

Yaml infrastrutturale

Nel repository dell'infrastruttura abbiamo il service:

apiVersion: v1
kind: Service
metadata:
 labels:
   id: app
 name: app
spec:
 ports:
 - port: 80
   protocol: TCP
   targetPort: 5000
 selector:
   id: app
 type: LoadBalancer

E deployment in deploy.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: app
spec:
 replicas: 10
 selector:
   matchLabels:
     id: app
     type: main
 template:
   metadata:
     labels:
       id: app
       type: main
   spec:
     containers:
     - image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v1
       name: app
       resources:
         limits:
           cpu: 100m
           memory: 100Mi

E un altro deployment in deploy-canary.yaml:

kind: Deployment
metadata:
 name: app-canary
spec:
 replicas: 0
 selector:
   matchLabels:
     id: app
     type: canary
 template:
   metadata:
     labels:
       id: app
       type: canary
   spec:
     containers:
     - image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
       name: app
       resources:
         limits:
           cpu: 100m
           memory: 100Mi

Nota che app-deploy attualmente non ha repliche definite.

Esecuzione del deployment iniziale

Per avviare il deployment iniziale, puoi eseguire manualmente il pipeline di GitlabCI nel ramo master. Dopo di che kubectl dovrebbe mostrare quanto segue:

Canary Deployment in Kubernetes #1: Gitlab CI

Vediamo app un deployment con 10 repliche e app-canary con 0. C'è anche un LoadBalancer a cui possiamo accedere attraverso curl l'IP esterno:

while true; do curl -s 35.198.149.232 | grep label; sleep 0.1; done

Canary Deployment in Kubernetes #1: Gitlab CI

Vediamo che la nostra applicazione di test restituisce solo 'v1'.

Esecuzione del deployment Canary

Passo 1: rilasciare una nuova versione per una parte degli utenti

Abbiamo impostato il numero di repliche a 1 nel file deploy-canary.yaml e l'immagine della nuova versione:

kind: Deployment
metadata:
 name: app-canary
spec:
 replicas: 1
 selector:
   matchLabels:
     id: app
     type: canary
 template:
   metadata:
     labels:
       id: app
       type: canary
   spec:
     containers:
     - image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
       name: app
       resources:
         limits:
           cpu: 100m
           memory: 100Mi

Nel file deploy.yaml abbiamo modificato il numero di repliche a 9:

kind: Deployment
metadata:
 name: app
spec:
 replicas: 9
 selector:
   matchLabels:
     id: app
...

Stiamo inviando queste modifiche nel repository, da cui verrà avviato il deployment (tramite GitlabCI) e vediamo infine:

Canary Deployment in Kubernetes #1: Gitlab CI

Il nostro Service punterà su entrambi i deployments, poiché entrambi hanno il selettore app. A causa della distribuzione casuale predefinita in Kubernetes, dovremmo vedere risposte diverse su ~ il 10% delle richieste:

Canary Deployment in Kubernetes #1: Gitlab CI

Lo stato attuale della nostra applicazione (GitOps, preso da Git come unica fonte di verità) è la presenza di due deployments con repliche attive, uno per ogni versione.

~il 10% degli utenti prova la nuova versione e la testa involontariamente. È ora di controllare la presenza di errori nei log e nei dati di monitoraggio per individuare eventuali problemi.

Passo 2: rilasciare una nuova versione per tutti gli utenti

Abbiamo deciso che tutto è andato bene e ora dobbiamo distribuire la nuova versione a tutti gli utenti. Per fare ciò, aggiorniamo semplicemente deploy.yaml installando la nuova versione dell'immagine e impostando il numero delle repliche a 10. In deploy-canary.yaml Impostiamo il numero di repliche a zero. Dopo il deploy il risultato sarà il seguente:

Canary Deployment in Kubernetes #1: Gitlab CI

In sintesi

Per me, avviare il deploy manualmente in questo modo aiuta a capire quanto sia facile configurarlo tramite k8s. Poiché Kubernetes permette di aggiornare tutto tramite l'API, questi passaggi possono essere automatizzati con script.

Un'altra cosa da implementare è il punto d'ingresso per il tester (LoadBalancer o tramite Ingress), tramite il quale sarà possibile accedere solo alla nuova versione. Questo può essere utilizzato per la visualizzazione manuale.

Negli articoli successivi esamineremo altre soluzioni automatizzate che implementano la maggior parte di ciò che abbiamo fatto.

Leggi anche altri articoli nel nostro blog:

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster