Автоматичні 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). Ці об'єкти розкривають додаток у службі 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 та піки затримок реєструються як події 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 разом із Плетіння флюсу або ДженкінсX. Якщо ви використовуєте JenkinsX, можете встановити Flagger із надбудовами jx.

Flagger підтримується Ткацькі вироби та забезпечує canary деплої у Weave Cloud. Проект тестується на GKE, EKS та «голому залізі» з kubeadm.

Якщо у вас є пропозиції щодо покращення Flagger, будь ласка, надішліть питання або PR на GitHub за адресою stefanprodan/flagger. Внески більш ніж вітаються!

Дякуємо Рею Цану.

Джерело: habr.com

Додати коментар або відгук