Canary Deployment în Kubernetes #1: Gitlab CI

Vom folosi Gitlab CI și GitOps manual pentru implementarea și utilizarea Canary deployment-ului în Kubernetes

Canary Deployment în Kubernetes #1: Gitlab CI

Articole din acest ciclu:

Vom realiza Canary deployment manual prin GitOps și crearea/modificarea resurselor esențiale Kubernetes. Acest articol este destinat în special pentru a familiariza cititorii cu modul în care funcționează Canary deployment în Kubernetes, deoarece există metode mai eficiente de automatizare pe care le vom explora în articolele următoare.


Canary Deployment în Kubernetes #1: Gitlab CI

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

Canary Deployment

În strategia Canary de actualizare, modificările sunt aplicate inițial doar pentru o parte a utilizatorilor. Prin monitorizare, date din jurnale, teste manuale sau alte canale de feedback, versiunea este testată înainte de a fi aplicată tuturor utilizatorilor.

Kubernetes Deployment (actualizare continuă)

Strategia implicită pentru Kubernetes Deployment este actualizarea continuă, unde un anumit număr de poduri cu noi versiuni de imagini sunt lansate. Dacă acestea sunt create fără probleme, podurile cu versiunile vechi ale imaginilor sunt terminate, iar noile poduri sunt create în paralel.

GitOps

Folosim GitOps în acest exemplu, deoarece:

  • folosim Git ca sursă unică de adevăr
  • folosim Git Operations pentru construire și implementare (nu sunt necesare comenzi, cu excepția git tag/merge)

Exemplu

Să adoptăm o bună practică — să avem un singur repo pentru codul aplicațiilor și unul pentru infrastructură.

Repozitoriu pentru aplicații

Aceasta este o API foarte simplă pe Python+Flask, care returnează un răspuns în format JSON. Vom construi pachetul prin GitlabCI și vom trimite rezultatul în Gitlab Registry. În registru avem două versiuni diferite de release-uri:

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

Singura diferență dintre ele este modificarea fișierului JSON returnat. Folosim această aplicație pentru a vizualiza cât se poate de simplu cu ce versiune comunicăm.

Repozitoriu de infrastructură

În acest repo vom implementa prin GitlabCI în Kubernetes, .gitlab-ci.yml arată în următorul mod:

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

Pentru a-l rula local, aveți nevoie de un cluster, puteți folosi Gcloud:

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

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

Trebuie să faceți un fork https://gitlab.com/wuestkamp/k8s-deployment-example-canary-infrastructure și să creați o variabilă KUBECONFIG în GitlabCI, care va conține configurația de acces kubectl la clusterul dvs.

Despre cum să obțineți acreditivele pentru cluster (Gcloud) se poate citi aici.

Yaml de infrastructură

În repository-ul de infrastructură avem service:

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

Și deployment în 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

Și un alt deployment în 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

Observați că app-deploy nu are încă replici definite.

Executarea deployment-ului inițial

Pentru a iniția deployment-ul inițial, puteți rula manual pipeline-ul GitlabCI pe ramura master. După aceasta kubectl ar trebui să afișeze următoarele:

Canary Deployment în Kubernetes #1: Gitlab CI

Vedem app deployment cu 10 replici și app-canary cu 0. De asemenea, există un LoadBalancer de pe care putem accesa prin curl prin IP-ul extern:

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

Canary Deployment în Kubernetes #1: Gitlab CI

Observăm că aplicația noastră de testare returnează doar "v1".

Executarea deployment-ului Canary

Pasul 1: lansați o nouă versiune pentru o parte dintre utilizatori

Am setat numărul de replici la 1 în fișierul deploy-canary.yaml și imaginea noii versiuni:

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

În fișierul deploy.yaml am schimbat numărul de replici la 9:

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

Facem push aceste modificări în repository-ul din care va fi lansat deployment-ul (prin GitlabCI) și observăm în final:

Canary Deployment în Kubernetes #1: Gitlab CI

Serviciul nostru va indica ambele deployment-uri, deoarece ambele au selectorul app. Datorită distribuției aleatoare implicite în Kubernetes, ar trebui să vedem răspunsuri diferite la aproximativ 10% dintre cereri:

Canary Deployment în Kubernetes #1: Gitlab CI

Starea actuală a aplicației noastre (GitOps, luată din Git ca sursă unică de adevăr) este că există două deployment-uri cu replici active, câte unul pentru fiecare versiune.

~10% dintre utilizatori se familiarizează cu noua versiune și o testează fără să vrea. Acum este timpul să verificăm erorile din jurnale și datele de monitorizare pentru a căuta probleme.

Pasul 2: lansați o nouă versiune pentru toți utilizatorii

Am decis că totul a decurs bine și acum trebuie să implementăm o nouă versiune pentru toți utilizatorii. Pentru aceasta, pur și simplu actualizăm deploy.yaml instalând o nouă versiune a imaginii și un număr de replici egal cu 10. În deploy-canary.yaml stabilim numărul de replici înapoi la 0. După desfășurare, rezultatul va fi următorul:

Canary Deployment în Kubernetes #1: Gitlab CI

În concluzie

Pentru mine, lansarea desfășurării manual în acest mod ajută să înțeleg cât de ușor poate fi configurată prin k8s. Deoarece Kubernetes permite actualizarea totul prin API, acești pași pot fi automatizați prin scripturi.

Încă un lucru care trebuie implementat este punctul de intrare al testerului (LoadBalancer sau prin Ingress), prin care se poate accesa doar noua versiune. Aceasta poate fi folosită pentru vizualizare manuală.

În următoarele articole vom verifica alte soluții automatizate care implementează majoritatea a ceea ce am realizat.

Citiți și alte articole de pe blogul nostru:

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster