Distribuzione Canary in Kubernetes #1: Gitlab CI

Utilizzeremo Gitlab CI e GitOps manuale per implementare e utilizzare la distribuzione Canary in Kubernetes

Distribuzione Canary in Kubernetes #1: Gitlab CI

Articoli di questa serie:

Eseguiremo manualmente la distribuzione di Canary tramite GitOps e creando/modificando le principali risorse Kubernetes. Questo articolo è destinato principalmente all'introduzione con come funziona la distribuzione in Kubernetes Canary, poiché esistono metodi di automazione più efficaci, che considereremo nei seguenti articoli.


Distribuzione Canary in Kubernetes #1: Gitlab CI

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

Distribuzione Canarie

Con la strategia Canary, gli aggiornamenti vengono prima applicati solo a un sottoinsieme di utenti. Attraverso il monitoraggio, i dati di registro, i test manuali o altri canali di feedback, la versione viene testata prima di essere rilasciata a tutti gli utenti.

Distribuzione Kubernetes (aggiornamento in sequenza)

La strategia predefinita per Kubernetes Deployment è l'aggiornamento in sequenza, in cui un certo numero di pod viene avviato con nuove versioni delle immagini. Se sono stati creati senza problemi, i pod con le vecchie versioni delle immagini vengono terminati e i nuovi pod vengono creati in parallelo.

GitOps

Utilizziamo GitOps in questo esempio perché:

  • utilizzando Git come un'unica fonte di verità
  • utilizziamo Git Operations per la creazione e la distribuzione (non sono necessari comandi diversi da git tag/merge)

esempio

Prendiamo una buona pratica: avere un repository per il codice dell'applicazione e uno per l'infrastruttura.

Repository dell'applicazione

Questa è un'API Python+Flask molto semplice che restituisce una risposta come JSON. Costruiremo il pacchetto tramite GitlabCI e invieremo il risultato al registro Gitlab. Nel registro abbiamo due diverse versioni di rilascio:

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

L'unica differenza tra loro è la modifica nel file JSON restituito. Utilizziamo questa applicazione per visualizzare nel modo più semplice possibile con quale versione stiamo comunicando.

Archivio dell'infrastruttura

In questa rapa distribuiremo tramite GitlabCI a Kubernetes, .gitlab-ci.yml assomiglia a questo:

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 eseguirlo da solo avrai bisogno di un cluster, puoi usare Gcloud:

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

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

Devi biforcare 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 tuo cluster.

Puoi leggere come ottenere le credenziali per un cluster (Gcloud) qui.

Yaml dell'infrastruttura

Nel repository dell'infrastruttura abbiamo il servizio:

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

E schieramento 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 schieramento in arrivo 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

Tieni presente che per la distribuzione dell'app non sono ancora state definite repliche.

Esecuzione della distribuzione iniziale

Per avviare la distribuzione iniziale, puoi avviare manualmente la pipeline GitlabCI sul ramo master. Dopo di che kubectl dovrebbe produrre quanto segue:

Distribuzione Canary in Kubernetes #1: Gitlab CI

Noi vediamo app distribuzione con 10 repliche e app-canary con 0. C'è anche un LoadBalancer da cui possiamo accedere tramite curl tramite IP esterno:

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

Distribuzione Canary in Kubernetes #1: Gitlab CI

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

Esecuzione della distribuzione Canary

Passaggio 1: rilascia una nuova versione per alcuni utenti

Impostiamo il numero di repliche su 1 nel file deploy-canary.yaml e nell'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

In archivio deploy.yaml abbiamo cambiato il numero di repliche a 9:

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

Inseriamo queste modifiche nel repository da cui inizierà la distribuzione (tramite GitlabCI) e vediamo come risultato:

Distribuzione Canary in Kubernetes #1: Gitlab CI

Il nostro servizio punterà a entrambe le distribuzioni, poiché entrambe dispongono del selettore di app. A causa della randomizzazione predefinita di Kubernetes, dovremmo vedere risposte diverse per circa il 10% delle richieste:

Distribuzione Canary in Kubernetes #1: Gitlab CI

Lo stato attuale della nostra applicazione (GitOps, tratto da Git as a Single Source Of Truth) è la presenza di due deploy con repliche attive, una per ciascuna versione.

Circa il 10% degli utenti acquisisce familiarità con una nuova versione e la testa involontariamente. Ora è il momento di verificare la presenza di errori nei registri e di monitorare i dati per individuare i problemi.

Passaggio 2: rilascia la nuova versione a tutti gli utenti

Abbiamo deciso che tutto è andato bene e ora dobbiamo distribuire la nuova versione a tutti gli utenti. Per fare questo aggiorniamo semplicemente deploy.yaml installando una nuova versione dell'immagine e il numero di repliche pari a 10. In deploy-canary.yaml reimpostiamo il numero di repliche su 0. Dopo la distribuzione, il risultato sarà il seguente:

Distribuzione Canary in Kubernetes #1: Gitlab CI

Riassumendo

Per me, eseguire manualmente la distribuzione in questo modo aiuta a capire con quanta facilità può essere configurata utilizzando k8s. Poiché Kubernetes ti consente di aggiornare tutto tramite un'API, questi passaggi possono essere automatizzati tramite script.

Un'altra cosa che deve essere implementata è un punto di ingresso del tester (LoadBalancer o tramite Ingress) attraverso il quale è possibile accedere solo alla nuova versione. Può essere utilizzato per la navigazione manuale.

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

Leggi anche altri articoli sul nostro blog:

Fonte: habr.com

Aggiungi un commento