Автоматични 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}

Уверете се, че подстановъчният символ 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

Събития:

Новата ревизия е открита podinfo.test
Скалиране нагоре podinfo.test
Чакане за завършване на деплоя 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
Чакане за завършване на деплоя 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   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

Генерация на забавяне:

наблюдайте 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 анализът може да бъде лесно разширен с уебхукове за изпълнение на системни тестове за интеграция/приемане, натоварващи тестове или всякакви други потребителски проверки. Тъй като 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