Ҷойгиркунии худкори канарӣ бо Flagger ва Istio

Ҷойгиркунии худкори канарӣ бо Flagger ва Istio

CD ҳамчун як таҷрибаи нармафзори корхона эътироф шудааст ва натиҷаи таҳаввулоти табиии принсипҳои муқарраршудаи CI мебошад. Бо вуҷуди ин, CD то ҳол хеле кам аст, шояд аз сабаби мураккабии идоракунӣ ва тарс аз ҷойгиркунии ноком, ки ба дастрасии система таъсир мерасонад.

Парчамгузор оператори манбаи кушодаи Kubernetes мебошад, ки ҳадафи бартараф кардани муносибатҳои нофаҳмо мебошад. Он пешбурди ҷобаҷогузории канариро бо истифода аз ченакҳои трафики Istio ва Prometheus барои таҳлили рафтори барномаҳо ҳангоми паҳнкунии идорашаванда автоматӣ мекунад.

Дар зер як дастури қадам ба қадам барои насб ва истифодаи Flagger дар Google Kubernetes Engine (GKE) оварда шудааст.

Таъсиси кластери Kubernetes

Шумо бо эҷоди кластери GKE бо иловаи Istio оғоз мекунед (агар шумо ҳисоби GCP надошта бошед, шумо метавонед сабти ном шавед дар ин ҷо - барои гирифтани қарзҳои ройгон).

Ба Google Cloud ворид шавед, лоиҳа эҷод кунед ва ҳисобро барои он фаъол созед. Утилитаи сатри фармонро насб кунед gcloud ва лоиҳаи худро бо gcloud init.

Лоиҳаи пешфарз, минтақаи ҳисобкунӣ ва минтақаро таъин кунед (иваз PROJECT_ID барои лоиҳаи шумо):

gcloud config set project PROJECT_ID
gcloud config set compute/region us-central1
gcloud config set compute/zone us-central1-a

Хидмати GKE-ро фаъол созед ва кластерро бо иловаҳои HPA ва Istio эҷод кунед:

gcloud services enable container.googleapis.com
K8S_VERSION=$(gcloud beta container get-server-config --format=json | jq -r '.validMasterVersions[0]')
gcloud beta container clusters create istio 
--cluster-version=${K8S_VERSION} 
--zone=us-central1-a 
--num-nodes=2 
--machine-type=n1-standard-2 
--disk-size=30 
--enable-autorepair 
--no-enable-cloud-logging 
--no-enable-cloud-monitoring 
--addons=HorizontalPodAutoscaling,Istio 
--istio-config=auth=MTLS_PERMISSIVE

Фармони боло як ҳавзи гиреҳи пешфарз, аз ҷумла ду VM эҷод мекунад n1-standard-2 (vCPU: 2, RAM 7,5 ГБ, диск: 30 ГБ). Идеалӣ, шумо бояд ҷузъҳои Istio-ро аз сарбории худ ҷудо кунед, аммо роҳи осони иҷро кардани Istio Pods дар ҳавзи махсуси гиреҳҳо вуҷуд надорад. Манифестҳои Истио танҳо барои хондан ҳисобида мешаванд ва GKE ҳама гуна тағиротро, ба монанди пайвастшавӣ ба гиреҳ ё ҷудо кардан аз подкаст бекор мекунад.

Муқаррар кардани эътимоднома барои kubectl:

gcloud container clusters get-credentials istio

Эҷоди нақши мудири кластер ҳатмӣ:

kubectl create clusterrolebinding "cluster-admin-$(whoami)" 
--clusterrole=cluster-admin 
--user="$(gcloud config get-value core/account)"

Асбоби сатри фармонро насб кунед Helm:

brew install kubernetes-helm

Homebrew 2.0 ҳоло барои дастрас аст Linux.

Эҷоди ҳисоби хидматӣ ва нақши кластер барои Tiller:

kubectl -n kube-system create sa tiller && 
kubectl create clusterrolebinding tiller-cluster-rule 
--clusterrole=cluster-admin 
--serviceaccount=kube-system:tiller

Tiller -ро дар фазои ном васеъ кунед kube-system:

helm init --service-account tiller

Шумо бояд истифодаи SSL байни Ҳелм ва Тиллерро баррасӣ кунед. Барои маълумоти бештар дар бораи муҳофизати насби Helm, нигаред docs.helm.sh

Танзимотро тасдиқ кунед:

kubectl -n istio-system get svc

Пас аз чанд сония, GCP бояд барои хидмат суроғаи IP-и беруна таъин кунад istio-ingressgateway.

Танзими Gateway Istio Ingress

Суроғаи IP-и статикиро бо ном эҷод кунед istio-gatewayбо истифода аз суроғаи IP шлюзи Istio:

export GATEWAY_IP=$(kubectl -n istio-system get svc/istio-ingressgateway -ojson | jq -r .status.loadBalancer.ingress[0].ip)
gcloud compute addresses create istio-gateway --addresses ${GATEWAY_IP} --region us-central1

Акнун ба шумо домени интернетӣ ва дастрасӣ ба сабти DNS-и худ лозим аст. Ду сабти A илова кунед (иваз кунед example.com ба домени шумо):

istio.example.com   A ${GATEWAY_IP}
*.istio.example.com A ${GATEWAY_IP}

Боварӣ ҳосил кунед, ки аломати ҷории DNS кор мекунад:

watch host test.istio.example.com

Барои пешниҳоди хидматҳо берун аз шабакаи хидматрасонӣ тавассути HTTP як шлюзи умумии Istio эҷод кунед:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: public-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"

Манбаи болоро ҳамчун public-gateway.yaml захира кунед ва сипас онро татбиқ кунед:

kubectl apply -f ./public-gateway.yaml

Ягон системаи истеҳсолӣ набояд дар Интернет бидуни SSL хидмат расонад. Барои муҳофизат кардани шлюзи Istio бо менеҷери сертификат, CloudDNS ва Let's Encrypt, лутфан хонед ҳуҷҷатҳо Парчамгир Г.К.Е.

Насбкунии Flagger

Иловаи GKE Istio намунаи Prometheus-ро дар бар намегирад, ки хидмати телеметрии Istio-ро тоза мекунад. Азбаски Flagger барои анҷом додани таҳлили канарӣ метрикаи Istio HTTP-ро истифода мебарад, шумо бояд конфигуратсияи зерини Prometheus-ро, ки бо схемаи расмии Istio Helm меояд, ҷойгир кунед.

REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/gke/istio-prometheus.yaml

Анбори Flagger Helm-ро илова кунед:

helm repo add flagger [https://flagger.app](https://flagger.app/)

Flaggerро ба фазои ном васеъ кунед istio-systemтавассути фаъол кардани огоҳиҳои Slack:

helm upgrade -i flagger flagger/flagger 
--namespace=istio-system 
--set metricsServer=http://prometheus.istio-system:9090 
--set slack.url=https://hooks.slack.com/services/YOUR-WEBHOOK-ID 
--set slack.channel=general 
--set slack.user=flagger

Шумо метавонед Flagger-ро дар ҳама гуна фазои ном насб кунед, ба шарте ки он метавонад бо хидмати Istio Prometheus дар порти 9090 муошират кунад.

Flagger дорои панели графикии Grafana барои таҳлили канария мебошад. Grafana -ро дар фазои ном насб кунед istio-system:

helm upgrade -i flagger-grafana flagger/grafana 
--namespace=istio-system 
--set url=http://prometheus.istio-system:9090 
--set user=admin 
--set password=change-me

Графанаро тавассути як дарвозаи кушода тавассути эҷоди хидмати виртуалӣ фош кунед (иваз example.com ба домени шумо):

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: grafana
  namespace: istio-system
spec:
  hosts:
    - "grafana.istio.example.com"
  gateways:
    - public-gateway.istio-system.svc.cluster.local
  http:
    - route:
        - destination:
            host: flagger-grafana

Манбаи болоро ҳамчун grafana-virtual-service.yaml захира кунед ва сипас онро татбиқ кунед:

kubectl apply -f ./grafana-virtual-service.yaml

Ҳангоми ҳаракат ба http://grafana.istio.example.com дар браузер, шумо бояд ба саҳифаи воридшавии Grafana равона карда шавед.

Ҷойгир кардани барномаҳои веб бо Flagger

Flagger Kubernetes-ро ҷойгир мекунад ва ба таври ихтиёрӣ ба таври худкор миқёсро васеъ мекунад (HPA), сипас як қатор объектҳоро (ҷойгиркунии Kubernetes, хидматҳои ClusterIP ва хидматҳои виртуалии Istio) эҷод мекунад. Ин объектҳо барномаро ба шабакаи хидматрасонӣ фош мекунанд ва таҳлил ва пешрафти канаро назорат мекунанд.

Ҷойгиркунии худкори канарӣ бо Flagger ва Istio

Фазои номи санҷиширо бо тазриқи Istio Sidecar фаъол созед:

REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master
kubectl apply -f ${REPO}/artifacts/namespaces/test.yaml

Воситаи васеъкунӣ ва автоматии васеъкунӣ эҷод кунед:

kubectl apply -f ${REPO}/artifacts/canaries/deployment.yaml
kubectl apply -f ${REPO}/artifacts/canaries/hpa.yaml

Барои тавлиди трафик ҳангоми таҳлили канария хидмати боркунии санҷиширо ҷобаҷо кунед:

helm upgrade -i flagger-loadtester flagger/loadtester 
--namepace=test

Захираи махсуси канарияро эҷод кунед (иваз кунед example.com ба домени шумо):

apiVersion: flagger.app/v1alpha3
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  progressDeadlineSeconds: 60
  autoscalerRef:
    apiVersion: autoscaling/v2beta1
    kind: HorizontalPodAutoscaler
    name: podinfo
  service:
    port: 9898
    gateways:
    - public-gateway.istio-system.svc.cluster.local
    hosts:
    - app.istio.example.com
  canaryAnalysis:
    interval: 30s
    threshold: 10
    maxWeight: 50
    stepWeight: 5
    metrics:
    - name: istio_requests_total
      threshold: 99
      interval: 30s
    - name: istio_request_duration_seconds_bucket
      threshold: 500
      interval: 30s
    webhooks:
      - name: load-test
        url: http://flagger-loadtester.test/
        timeout: 5s
        metadata:
          cmd: "hey -z 1m -q 10 -c 2 http://podinfo.test:9898/"

Манбаи дар боло зикршударо ҳамчун podinfo-canary.yaml захира кунед ва сипас онро татбиқ кунед:

kubectl apply -f ./podinfo-canary.yaml

Таҳлили дар боло овардашуда, агар муваффақ бошад, панҷ дақиқа кор мекунад ва ҳар ним дақиқа метрикаи HTTP-ро тафтиш мекунад. Шумо метавонед бо истифода аз формулаи зерин вақти ҳадди ақалро барои тасдиқ ва пешбурди ҷойгиркунии канария муайян кунед: interval * (maxWeight / stepWeight). Майдонҳои Canary CRD ҳуҷҷатгузорӣ карда шудаанд дар ин ҷо.

Пас аз чанд сония, Flagger объектҳои канариро эҷод мекунад:

# applied 
deployment.apps/podinfo
horizontalpodautoscaler.autoscaling/podinfo
canary.flagger.app/podinfo
# generated 
deployment.apps/podinfo-primary
horizontalpodautoscaler.autoscaling/podinfo-primary
service/podinfo
service/podinfo-canary
service/podinfo-primary
virtualservice.networking.istio.io/podinfo

Браузерро кушоед ва ба он равед app.istio.example.com, шумо бояд рақами версияро бинед барномаҳои намоишӣ.

Таҳлили худкори канария ва таблиғ

Flagger як ҳалқаи назоратро амалӣ мекунад, ки трафикро тадриҷан ба канария интиқол медиҳад ва ҳангоми чен кардани ченакҳои калидии иҷроиш ба монанди суръати муваффақияти дархости HTTP, давомнокии миёнаи дархост ва саломатии поддонҳо. Дар асоси таҳлили KPI, канария пешбарӣ ё қатъ карда мешавад ва натиҷаҳои таҳлил дар Slack нашр карда мешаванд.

Ҷойгиркунии худкори канарӣ бо Flagger ва Istio

Ҷойгиркунии Canary вақте оғоз мешавад, ки яке аз объектҳои зерин тағир меёбад:

  • Ҷойгиркунии PodSpec (тасвири контейнер, фармон, портҳо, env ва ғайра)
  • ConfigMaps ҳамчун ҳаҷм насб карда мешаванд ё ба тағирёбандаҳои муҳити зист харита карда мешаванд
  • Сиррҳо ҳамчун ҳаҷм насб карда мешаванд ё ба тағирёбандаҳои муҳити зист табдил дода мешаванд

Ҳангоми навсозии тасвири контейнер canary deploy -ро иҷро кунед:

kubectl -n test set image deployment/podinfo 
podinfod=quay.io/stefanprodan/podinfo:1.4.1

Flagger муайян мекунад, ки версияи ҷойгиркунӣ тағир ёфтааст ва таҳлили онро оғоз мекунад:

kubectl -n test describe canary/podinfo

Events:

New revision detected podinfo.test
Scaling up podinfo.test
Waiting for podinfo.test rollout to finish: 0 of 1 updated replicas are available
Advance podinfo.test canary weight 5
Advance podinfo.test canary weight 10
Advance podinfo.test canary weight 15
Advance podinfo.test canary weight 20
Advance podinfo.test canary weight 25
Advance podinfo.test canary weight 30
Advance podinfo.test canary weight 35
Advance podinfo.test canary weight 40
Advance podinfo.test canary weight 45
Advance podinfo.test canary weight 50
Copying podinfo.test template spec to podinfo-primary.test
Waiting for podinfo-primary.test rollout to finish: 1 of 2 updated replicas are available
Promotion completed! Scaling down podinfo.test

Ҳангоми таҳлил натиҷаҳои канариро тавассути Grafana пайгирӣ кардан мумкин аст:

Ҷойгиркунии худкори канарӣ бо Flagger ва Istio

Лутфан таваҷҷӯҳ намоед, ки агар дар ҷараёни таҳлили канария тағйироти нав ба ҷойгиркунӣ татбиқ карда шаванд, Flagger марҳилаи таҳлилро аз нав оғоз мекунад.

Рӯйхати ҳамаи канареяҳоро дар кластери худ созед:

watch kubectl get canaries --all-namespaces
NAMESPACE   NAME      STATUS        WEIGHT   LASTTRANSITIONTIME
test        podinfo   Progressing   15       2019-01-16T14:05:07Z
prod        frontend  Succeeded     0        2019-01-15T16:15:07Z
prod        backend   Failed        0        2019-01-14T17:05:07Z

Агар шумо огоҳиҳои Slack-ро фаъол карда бошед, шумо паёмҳои зеринро хоҳед гирифт:

Ҷойгиркунии худкори канарӣ бо Flagger ва Istio

Бозгашти худкор

Ҳангоми таҳлили канарӣ, шумо метавонед хатогиҳои синтетикии HTTP 500 ва таъхири баланди посухро эҷод кунед, то бубинед, ки оё Flagger густаришро қатъ мекунад.

Пойгоҳи санҷишӣ эҷод кунед ва дар он амалҳои зеринро иҷро кунед:

kubectl -n test run tester 
--image=quay.io/stefanprodan/podinfo:1.2.1 
-- ./podinfo --port=9898
kubectl -n test exec -it tester-xx-xx sh

Эҷоди хатогиҳои HTTP 500:

watch curl http://podinfo-canary:9898/status/500

Насли таъхир:

watch curl http://podinfo-canary:9898/delay/1

Вақте ки шумораи санҷишҳои ноком ба ҳадди ниҳоӣ мерасад, трафик ба канали ибтидоӣ бармегардад, канарӣ ба сифр баробар мешавад ва ҷойгиркунӣ ҳамчун ноком қайд карда мешавад.

Хатогиҳои канарӣ ва таъхирҳои таъхир ҳамчун рӯйдодҳои Kubernetes сабт карда мешаванд ва аз ҷониби Flagger дар формати JSON сабт карда мешаванд:

kubectl -n istio-system logs deployment/flagger -f | jq .msg

Starting canary deployment for podinfo.test
Advance podinfo.test canary weight 5
Advance podinfo.test canary weight 10
Advance podinfo.test canary weight 15
Halt podinfo.test advancement success rate 69.17% < 99%
Halt podinfo.test advancement success rate 61.39% < 99%
Halt podinfo.test advancement success rate 55.06% < 99%
Halt podinfo.test advancement success rate 47.00% < 99%
Halt podinfo.test advancement success rate 37.00% < 99%
Halt podinfo.test advancement request duration 1.515s > 500ms
Halt podinfo.test advancement request duration 1.600s > 500ms
Halt podinfo.test advancement request duration 1.915s > 500ms
Halt podinfo.test advancement request duration 2.050s > 500ms
Halt podinfo.test advancement request duration 2.515s > 500ms
Rolling back podinfo.test failed checks threshold reached 10
Canary failed! Scaling down podinfo.test

Агар шумо огоҳиномаҳои Slack-ро фаъол карда бошед, пас аз гузаштани мӯҳлат ё расидан ба шумораи максималии санҷишҳои ноком дар таҳлил шумо паём мегиред:

Ҷойгиркунии худкори канарӣ бо Flagger ва Istio

Дар охир

Иҷрои як шабакаи хидматрасонӣ ба монанди Istio, ба ғайр аз Kubernetes, ченакҳо, гузоришҳо ва протоколҳои автоматиро таъмин мекунад, аммо густариши сарбории корӣ ҳанӯз аз абзорҳои беруна вобаста аст. Flagger ҳадаф дорад, ки онро тавассути илова кардани қобилиятҳои Istio тағир диҳад таъминоти прогрессивй.

Flagger бо ҳама гуна ҳалли Kubernetes CI/CD мувофиқ аст ва таҳлили канариро бо осонӣ васеъ кардан мумкин аст. вебхукҳо барои анҷом додани санҷишҳои ҳамгироӣ/қабули система, санҷишҳои сарборӣ ё дигар санҷишҳои фармоишӣ. Азбаски Flagger декларатив аст ва ба рӯйдодҳои Kubernetes вокуниш нишон медиҳад, онро метавон дар қубурҳои GitOps дар якҷоягӣ бо Weave Flux ё ҶенкинсX. Агар шумо JenkinsX-ро истифода баред, шумо метавонед Flagger-ро бо иловаҳои jx насб кунед.

Flagger дастгирӣ карда мешавад Корҳои бофандагӣ ва ҷойгиркунии канарҳоро дар Абри бофтан. Лоиҳа дар GKE, EKS ва металлҳои урён бо кубеадм озмуда мешавад.

Агар шумо барои беҳтар кардани Flagger пешниҳоде дошта бошед, лутфан масъала ё PR-ро дар GitHub ирсол кунед stefanprodan / flagger. Ҳиссагузориҳо беш аз хуш омадед!

Спасибо Рэй Цанг.

Манбаъ: will.com

Илова Эзоҳ