Автоматизирани canary деплойменти с Flagger и Istio

Автоматизирани canary деплойменти с Flagger и Istio

CD е признато за практика в корпоративния софтуер, и това е резултат от естествената еволюция на утвърдените принципи на CI. Въпреки това, CD все още е сравнително рядко явление, вероятно заради сложността на управлението и страха от неуспешни деплойменти, които влияят на наличността на системата.

Flagger е оператор на 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)"

Инсталирайте командния инструмент 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 и 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. Добавете две A записа (заменете example.com с вашия домейн):

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

Уверете се, че wildcard 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 
--namespace=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

Събития:

Новата ревизия е открита podinfo.test
Увеличаване на podinfo.test
Изчаква под-rolling на podinfo.test да завърши: 0 от 1 актуализирани реплики са налични
Увеличаване на canary теглото на podinfo.test 5
Увеличаване на canary теглото на podinfo.test 10
Увеличаване на canary теглото на podinfo.test 15
Увеличаване на canary теглото на podinfo.test 20
Увеличаване на canary теглото на podinfo.test 25
Увеличаване на canary теглото на podinfo.test 30
Увеличаване на canary теглото на podinfo.test 35
Увеличаване на canary теглото на podinfo.test 40
Увеличаване на canary теглото на podinfo.test 45
Увеличаване на canary теглото на podinfo.test 50
Копиране на шаблона на podinfo.test в podinfo-primary.test
Изчаква под-rolling на podinfo-primary.test да завърши: 1 от 2 актуализирани реплики са налични
Промоцията е завършена! Намаляване на 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   Неуспешно    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

Започване на canary разгръщане за podinfo.test
Напредък на podinfo.test canary тегло 5
Напредък на podinfo.test canary тегло 10
Напредък на podinfo.test canary тегло 15
Спиране на напредъка на podinfo.test поради успехова скорост 69.17% < 99%
Спиране на напредъка на podinfo.test поради успехова скорост 61.39% < 99%
Спиране на напредъка на podinfo.test поради успехова скорост 55.06% < 99%
Спиране на напредъка на podinfo.test поради успехова скорост 47.00% < 99%
Спиране на напредъка на podinfo.test поради успехова скорост 37.00%  500ms
Спиране на напредъка на podinfo.test продължителност на заявката 1.600s > 500ms
Спиране на напредъка на podinfo.test продължителност на заявката 1.915s > 500ms
Спиране на напредъка на podinfo.test продължителност на заявката 2.050s > 500ms
Спиране на напредъка на podinfo.test продължителност на заявката 2.515s > 500ms
Върщане на podinfo.test при достигане на прага на неуспешните проверки 10
Canary неуспешно! Мащабиране на podinfo.test надолу

Ако сте активирали уведомленията в Slack, ще получите съобщение, когато се превиши времето за изпълнение или достигне максималният брой неуспешни проверки по време на анализа:

Автоматизирани canary деплойменти с Flagger и Istio

В заключение

Стартирането на service mesh, като Istio, в допълнение към Kubernetes, предоставя автоматични метрики, логове и протоколи, но разгръщането на натоварвания все още зависи от външни инструменти. Flagger се стреми да промени това, добавяйки възможности на Istio за прогресивно разгръщане.

Flagger е съвместим с всякакви CI/CD решения за Kubernetes и canary анализът може лесно да се разшири с webhooks за извършване на системни тестове за интеграция/приемане, натоварващи тестове или всякакви други потребителски проверки. Тъй като Flagger е декларативен и реагира на събития в Kubernetes, той може да се използва в GitOps пайплайни заедно с Weave Flux или JenkinsX. Ако използвате JenkinsX, можете да инсталирате Flagger с jx надстройки.

Flagger се поддържа от Weaveworks и осигурява canary разгръщания в Weave Cloud. Проектът се тества на GKE, EKS и 'голо желязо' с kubeadm.

Ако имате предложения за подобрения на Flagger, моля, изпратете запитване или PR на GitHub на адреса stefanprodan/flagger. Вноските са повече от добре дошли!

Благодаря Рей Чан.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster