Canary Deployment у Kubernetes #1: Gitlab CI

Мы будзем выкарыстоўваць Gitlab CI і ручной GitOps для ўкаранення і выкарыстання Canary-дэплою ў Kubernetes

Canary Deployment у Kubernetes #1: Gitlab CI

Артыкулы з гэтага цыклу:

Выконваць Canary-дэплой мы будзем рукамі праз GitOps і стварэнне/змена асноўных рэсурсаў Kubernetes. Гэты артыкул прызначаны ў першую чаргу для знаёмства. з тым, як працуе ў Kubernetes Canary дэплой, бо ёсць больш эфектыўныя спосабы аўтаматызацыі, якія мы разгледзім у наступных артыкулах.


Canary Deployment у Kubernetes #1: Gitlab CI

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

Канарскае разгортванне

Пры Canary-стратэгіі абнаўлення спачатку прымяняюцца толькі для часткі карыстальнікаў. Праз маніторынг, дадзеныя з логаў, ручное тэсціраванне або іншыя каналы зваротнай сувязі рэліз тэстуецца перад яго прымяненнем для ўсіх карыстальнікаў.

Kubernetes Deployment (rolling update)

Стратэгія па змаўчанні для Kubernetes Deployment - гэта rolling-update, дзе запускаецца пэўную колькасць подаў з новымі версіямі вобразаў. Калі яны стварыліся без праблем, поды са старымі версіямі выяў завяршаюцца, а новыя поды ствараюцца раўналежна.

GitOps

Мы выкарыстоўваем GitOps у гэтым прыкладзе, так як мы:

  • выкарыстоўваем Git як адзіную крыніцу ісціны
  • выкарыстоўваем Git Operations для зборкі і дэплою (ніякіх каманд, акрамя git tag/merge не трэба)

Прыклад

Возьмем добрую практыку - мець адзін рэпазітар для кода прыкладанняў і адзін для інфраструктуры.

Рэпазітар для прыкладанняў

Гэта вельмі простая API на Python+Flask, якая вяртае адказ у выглядзе JSON. Мы збярэм пакет праз GitlabCI і запушым вынік у Gitlab Registry. У рэгістры ў нас ёсць дзве розныя версіі рэлізаў:

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

Адзіная розніца паміж імі гэтая змена які вяртаецца JSON-файла. Мы выкарыстоўваем гэта дадатак для максімальна простай візуалізацыі таго, з якой версіяй мы маем зносіны.

Інфраструктурны рэпазітар

У гэтай рэпе мы будзем дэплоіць праз GitlabCI у Kubernetes, .gitlab-ci.yml выглядае наступным чынам:

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

Для яго запуску самастойна вам спатрэбіцца кластар, можна выкарыстоўваць Gcloud:

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

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

Вам трэба зрабіць форк https://gitlab.com/wuestkamp/k8s-deployment-example-canary-infrastructure і стварыць зменную KUBECONFIG у GitlabCI, якая будзе змяшчаць канфіг для доступу kubectl да вашага кластара.

Пра тое, як атрымаць уліковыя дадзеныя для кластара (Gcloud) можна пачытаць вось тут.

Інфраструктурны Yaml

У інфраструктурным рэпазітары ў нас ёсць service:

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

І deployment у 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

І іншы deployment у 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

Заўважце, што app-deploy пакуль не мае пэўных рэплік.

Выкананне пачатковага дэплою

Для запуску пачатковага deployment вы можаце запусціць пайплайн GitlabCI ўручную ў майстар-галінцы. Пасля гэтага kubectl павінен вывесці наступнае:

Canary Deployment у Kubernetes #1: Gitlab CI

Мы бачым app deployment c 10 рэплікамі і app-canary з 0. Таксама ёсць LoadBalancer з якога мы можам звяртацца праз curl па External IP:

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

Canary Deployment у Kubernetes #1: Gitlab CI

Мы бачым, што наша тэставае дадатак вяртае толькі "v1".

Выкананне Canary дэплоя

Крок 1: выпусціць новую версію для часткі карыстальнікаў

Мы ўсталявалі колькасць рэплік у 1 у файле deploy-canary.yaml і выява новай версіі:

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

У файле deploy.yaml мы змянілі колькасць рэплік да 9:

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

Мы пушым гэтыя змены ў рэпазітар, з якога запусціцца дэплой (праз GitlabCI) і бачым у выніку:

Canary Deployment у Kubernetes #1: Gitlab CI

Наш Service будзе паказваць на абодва дэплоі, так як у абодвух ёсць селектар app. З-за выпадковага размеркавання па змаўчанні ў Kubernetes мы павінны ўбачыць розныя адказы на ~ 10% запытаў:

Canary Deployment у Kubernetes #1: Gitlab CI

Бягучы стан нашага прыкладання (GitOps, узяты з Git як з Single Source Of Truth) гэта наяўнасць двух deployments c актыўнымі рэплікамі, па адным для кожнай версіі.

~10% карыстачоў знаёмяцца з новай версіяй і ненаўмысна тэстуюць яе. Цяпер настаў час праверыць наяўнасць памылак у логах і даных маніторынгу для пошуку праблем.

Крок 2: выпусціць новую версію для ўсіх карыстальнікаў

Мы вырашылі, што ўсё прайшло добра і зараз нам трэба разгарнуць новую версію на ўсіх карыстальнікаў. Для гэтага мы проста абнаўляем deploy.yaml усталёўваючы новую версію выявы і колькасць рэплік, роўнае 10. У deploy-canary.yaml мы ўсталёўваем колькасць рэплік роўнае зваротна 0. Пасля дэплою вынік будзе наступным:

Canary Deployment у Kubernetes #1: Gitlab CI

Падводзячы вынік

Для мяне запуск дэплою ўручную такім чынам дапамагае зразумець як лёгка ен можа быць настроены пры дапамозе k8s. Так як Kubernetes дазваляе абнаўляць усе праз API, гэтыя крокі можна аўтаматызаваць праз скрыпты.

Яшчэ адна рэч, якую трэба рэалізаваць – гэта кропка ўваходу тэсціроўшчыка (LoadBalancer або праз Ingress), праз якую можна атрымаць доступ толькі да новай версіі. Яна можа быць выкарыстана для прагляду ўручную.

У наступных артыкулах мы праверым іншыя аўтаматызаваныя рашэнні, якія рэалізуюць большасць з таго, што мы зрабілі.

Таксама чытайце іншыя артыкулы ў нашым блогу:

Крыніца: habr.com

Дадаць каментар