Аўтаматычныя canary дэплоі з Flagger і Istio

Аўтаматычныя canary дэплоі з Flagger і Istio

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

Флаггер - Гэта аператар Kubernetes з адкрытым зыходным кодам, мэта якога - выключыць заблытаныя ўзаемасувязі. Ён аўтаматызуе прасоўванне canary дэплояў з выкарыстаннем зрушэння трафіку 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

Прыведзеная вышэй каманда створыць пул нод па змаўчанні, які ўключае дзве ВМ n1-standard-2 (vCPU: 2, RAM 7,5 GB, дыск: 30 GB). У ідэале варта ізаляваць кампаненты Istio ад сваіх працоўных нагрузак, але простага спосабу запуску подаў Istio у вылучаным пуле нод не існуе. Маніфесты Istio лічацца даступнымі толькі для чытання, і GKE будзе адмяняць любыя змены, напрыклад, прывязку да ноды або адлучэнне ад пода.

Наладзьце уліковыя дадзеныя для kubectl:

gcloud container clusters get-credentials istio

Стварыце прывязку ролі адміністратара кластара:

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

Усталюеце прыладу каманднага радка шлем:

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 і Tiller. Для атрымання дадатковай інфармацыі аб абароне ўстаноўкі Helm гл. docs.helm.sh

Пацвердзіце наладкі:

kubectl -n istio-system get svc

Праз некалькі секунд GCP павінен прызначыць вонкавы IP-адрас для сэрвісу istio-ingressgateway.

Настройка ўваходнага шлюза Istio

Стварыце статычны 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. Дадайце два запісы А (заменіце example.com на свой дамен):

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

Пераканайцеся, што падстановачны сімвал DNS працуе:

watch host test.istio.example.com

Стварыце агульны шлюз Istio для прадастаўлення паслуг па-за межамі service mesh па HTTP:

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 з дапамогай cert-manager, CloudDNS і Let's Encrypt, прачытайце, калі ласка, дакументацыю Flagger GKE.

Ўстаноўка Flagger

Надбудова GKE Istio не ўключае асобнік Prometheus, які займаецца ачысткай службы тэлеметрыі Istio. Паколькі Flagger выкарыстоўвае метрыкі Istio HTTP для выканання canary аналізу, вам неабходна задэплоіць наступную канфігурацыю 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 для canary аналізу. Усталюйце 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

Раскрыйце Grafana праз адкрыты шлюз, стварыўшы віртуальны сэрвіс (заменіце 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). Гэтыя аб'екты раскрываюць прыкладанне ў service mesh і кіруюць canary аналізам і прасоўваннем.

Аўтаматычныя canary дэплоі з 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

Разгарніце сэрвіс тэставай нагрузкі для генерацыі трафіку падчас canary аналізу:

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

Стварыце карыстацкі canary рэсурс (заменіце 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 кожныя паўхвіліны. Вы можаце вызначыць мінімальны час, неабходны для праверкі і прасоўвання canary дэплою, па наступнай формуле: interval * (maxWeight / stepWeight). Палі Canary CRD дакументуюцца тут.

Праз пару секунд Flagger створыць canary аб'екты:

# 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, вы павінны ўбачыць нумар версіі дэма-прыкладанні.

Аўтаматычны canary аналіз і прасоўванне

Flagger рэалізуе цыкл кіравання, які паступова перамяшчае трафік на canary, адначасова вымяраючы ключавыя паказчыкі прадукцыйнасці, напрыклад, узровень паспяховасці HTTP-запытаў, сярэднюю працягласць запытаў і працаздольнасць пода. На аснове аналізу KPI canary прасоўваецца ці перарываецца, а вынікі аналізу публікуюцца ў Slack.

Аўтаматычныя canary дэплоі з Flagger і Istio

Canary дэплой запускаецца пры змене аднаго з наступных аб'ектаў:

  • Дэплой PodSpec (вобраз кантэйнера, каманда, парты, env і г.д.)
  • ConfigMaps мантуюцца як тамы або зменьваюцца ў зменныя асяроддзя
  • Сакрэты мантуюцца як тамы або зменьваюцца ў зменныя асяроддзі

Запуск canary дэплою пры абнаўленні выявы кантэйнера:

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

Падчас аналізу вынікі canary можна адсочваць з дапамогай Grafana:

Аўтаматычныя canary дэплоі з Flagger і Istio

Звярніце ўвагу: калі новыя змены прымяніць у дачыненні да дэплою падчас canary аналізу, то 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, то атрымаеце наступныя паведамленні:

Аўтаматычныя canary дэплоі з Flagger і Istio

Аўтаматычны адкат

Падчас canary аналізу можна генераваць сінтэтычныя памылкі 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

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

Памылкі canary і пікі затрымак рэгіструюцца як падзеі 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, то атрымаеце паведамленне, калі будзе перавышаны крайні тэрмін выканання ці дасягненні максімальнай колькасці няўдалых праверак падчас аналізаў:

Аўтаматычныя canary дэплоі з Flagger і Istio

У заключэнне

Запуск service mesh, напрыклад, Istio, у дадатак да Kubernetes падасць аўтаматычныя метрыкі, логі і пратаколы, але дэплой працоўных нагрузак усё яшчэ залежыць ад вонкавых прылад. Flagger імкнецца змяніць гэтую сітуацыю, дадаючы Istio магчымасці прагрэсіўнай пастаўкі.

Flagger сумяшчальны з любымі CI/CD-рашэннямі для Kubernetes, і канарэчны аналіз можна лёгка пашырыць з дапамогай вэбхукаў для выканання сістэмных тэстаў інтэграцыі/прыёмкі, нагрузачных тэстаў ці любых іншых карыстацкіх праверак. Паколькі Flagger з'яўляецца дэкларатыўным і рэагуе на падзеі Kubernetes, яго можна выкарыстоўваць у пайплайнах GitOps разам з Weave Flux або ДжэнкінсX. Калі вы карыстаецеся JenkinsX, можаце ўсталяваць Flagger з надбудовамі jx.

Flagger падтрымліваецца Weaveworks і забяспечвае canary дэплоі ў Weave Cloud. Праект тэстуецца на GKE, EKS і "галом жалезе" з kubeadm.

Калі ў вас ёсць прапановы па паляпшэнні Flagger, калі ласка, адпраўце пытанне ці PR на GitHub па адрасе stefanprodan/flagger. Узносы больш чым вітаюцца!

Дзякуй Рэю Цану.

Крыніца: habr.com

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