Как стать автором
Обновить
97.09
Nixys
DevOps, DevSecOps, MLOps — системный IT-интегратор

Canary деплой с Jenkins-X, Istio и Flagger

Время на прочтение 8 мин
Количество просмотров 3.9K
Автор оригинала: Kim Wuestkamp

Доброго времени суток, читатель!


Вот мы и подошли к заключительной части цикла статей о Канареечных релизах в Kubernetes и методах их реализации. Желаю приятного чтения и надеюсь, что данный цикл был для вас полезным.




Использование решения Jenkins X для выполнения Canary деплоя в кластере Kubernetes





В этом цикле:


  1. Canary Deployment через GitlabCI + GitOps/Manual Approach
  2. Canary Deployment через Argo Rollouts
  3. Canary Deployment с Istio
  4. (эта статья)

Что мы будем делать здесь?


Мы создадим Jenkins X k8s кластер и тестовое приложение на Python шаг за шагом. Вы можете повторять по примеру, либо просто читать, смотреть иллюстрации и результаты для получения представления о взаимодействии JenkinsX+Flagger+Istio сanary deployment и решить для себя, стоит ли эта связка более глубокого изучения.


Canary Deployment


Надеемся, что вы читали первую часть, где мы кратко объясняли что такое сanary deployment и показывали как его реализовать через стандартные ресурсы Kubernetes.


Jenkins X


И мы предполагаем, что читая эту статью, вы уже имеете представление о том, что такое Jenkins X. Если нет, то вы можете почитать о нем здесь.


Istio


Также, мы надеемся, что вы знаете что такое Istio. Если нет, то вы можете почитать о нем здесь. Вам также стоит прочитать часть 3, где мы осуществляли Canary deployment при помощи Istio, для лучшего понимания.


Flagger


Flagger это оператор Kubernetes, который автоматизирует сanary deployments используя Istio, Linkerd, App Mesh, NGINX, Contour или Gloo routing для управления трафиком и метрики Prometheus для canary-аналитики. Canary-аналитика может быть расширена с помощью веб-хуков для проведения тестов доступа, нагрузочных испытаний или любой другой проверки. (источник)

Создаем тестовую инфраструктуру и приложение


Мы будем использовать инструмент командной строки Jenkins X jx для создания кластера Kubernetes, репозитория Github и пробного приложения, он отлично подходит для создания быстрого примера.


Jenkins X k8s кластер


Первым делом мы создаем Jenkins X кластер, здесь мы используем Gcloud:


jx create cluster gke -n jenkinsx --machine-type n1-standard-4

Вам нужно выбрать тип “Serverless Jenkins X Pipelines with Tekton” и привязать все к вашему Github аккаунту. Это автоматически создаст два Github репозитория для stage и production окружений.


Далее мы установим некоторые дополнения (addons):


jx create addon istio
jx create addon flagger
jx create addon prometheus

Если вы столкнетесь с проблемами с Istio (у меня отсутствовали метрики istio_requests_total в Prometheus), вы можете установить Istio вручную:


istioctl manifest generate --set values.kiali.enabled=true --set values.tracing.enabled=true --set values.grafana.enabled=true --set values.prometheus.enabled=true > istio.yaml
kubectl -f istio.yaml install

Установка Flagger через jx автоматически внедрит Istio sidecar в поды namespace jx-production. Проверяем:


kubectl get ns -L istio-injection

Добавьте label istio-injection: enabled к любому namespace, в поды которого Istio sidecar должен быть внедрен.


Test App / Quickstart


Теперь ждем пока jxing-nginx-ingress-controller в namespace kube-system получит External IP. Затем создаем простое python-приложение:


jx create quickstart --project-name python-test

Выбираем тип python-http. Вы можете установить любой другой, потому что canary deployment работает для всех типов. Это должно быть что-то предоставляющее простые HTTP endpoints для тестовых нужд.


Jenkins X автоматически создаст Github репозиторий для приложения.


Я изменил do_GET метод в сгенерированном app.py, что бы он возвращал текст, а не изображение:


def do_GET(self):
 self.send_response(200)
 self.send_header('Content-type','text/html')
 self.end_headers()
 # Send the html message
 output = 'v1'
 self.wfile.write(output.encode('utf-8'))
 return

Окружения


Jenkins X создаст три окружения по умолчанию (jx get env):





Каждое окружения имеет свой собственный Git-репозиторий, где все сконфигурировано через GitOps. Окружения на самом деле сконфигурированы из Helm Charts и ссылаются на все приложения + версии, установленные в них, через require.yaml.


Начальный Deployment


При создании нового quickstart приложения, или импорта существующего (jx import), он будет выпущен как версия 0.0.1 в stage окружении. Так происходит, потому что PROMOTE установлен в Auto для stage окружения. Мы можем видеть их как Pull Request в stage репозитории, который Jenkins X автоматически создает и сливает. Мы можем отслеживать все действия Pipeline через:


 jx get activities -w

После того как pipelines завершатся успешно, мы можем проверить доступность приложений:


jx get applications


                        Jenkins X работает автоматически с версиями Semver

В данный момент мы видим, что версия 0.0.1 задеплоена на stage, в prod пока ничего нет. Мы можем проверить следующим образом:


kubectl -n jx-staging get all       # shows the app
kubectl -n jx-production get all    # shows nothing

У нас должна быть возможность открыть доступ к stage приложению, через предоставленный URL:





Перемещение в production


(Прежде чем переходить в production я внес ещё одно изменение, которое увеличило версию до 0.0.2)


Перемещение (promote) в production по факту означает “деплой”. Через jx get env мы можем увидеть, что production требует ручного деплоя, поэтому мы делаем:


jx promote --version 0.0.2 --env production

Это автоматически создаст Pull Request в Jenkins X production Github репозиторий. И сейчас jx get applications покажет версию 0.0.2 на stage и так же на production:





Мы можем также переместить приложение в production через изменение requirements.yaml файла вручную в репозитории prod окружения.


Включение Canary для prod окружения


Прямо сейчас деплой в prod или stage производится без использования canary, но через rolling-rollouts Kubernetes.


В нашем репозитории для тестового приложения Python, Jenkins X автоматически создал через хелм-чарт. Если мы откроем файл charts/APP_NAME/values.yaml, то можем увидеть различные варианты Flagger Canary:


# Canary deployments
# If enabled, Istio and Flagger need to be installed in the cluster
canary:
 enabled: false
 progressDeadlineSeconds: 60
 canaryAnalysis:
   interval: "1m"
   threshold: 5
   maxWeight: 60
   stepWeight: 20
   # WARNING: Canary deployments will fail and rollback if there is no traffic that will generate the below specified metrics.
   metrics:
     requestSuccessRate:
       threshold: 99
       interval: "1m"
     requestDuration:
       threshold: 1000
       interval: "1m"
 # The host is using Istio Gateway and is currently not auto-generated
 # Please overwrite the `canary.host` in `values.yaml` in each environment repository (e.g., staging, production)
 host: acme.com

С данными настройками успешный canary deployment пройдет примерно за 3 минуты, по 1 минуте на каждый шаг: 20%, 40%, 60%.


Тем не менее по умолчанию сanary отключен через canary: enabled: false.


Мы можем изменить этот параметр для каждого Jenkins X окружения, что я и делаю для production репозитория environment-jenkinsx-production. Можно аналогично переопределить эти значения в Python, потому что репозитории с окружениями представляют собой Helm charts и ссылаются на все развернутые приложения через requirements.yaml. Я добавил следующий env/values.yaml в репозиторий environment-jenkinsx-production:


...
jenkinsx-istio-canary-python-test:
 canary:
   enabled: true
   host: jenkinsx-istio-canary-python-test.35.204.67.7.nip.io

  • Домен xxx.IP_ADDRESS.nip.io будет просто перенапрален на IP_ADDRESS. Отлично подходит для простого тестирования по доменному имени.
  • host: будет именем хоста Istio, через которое он сможет принимать запросы. Найдем внешний IP-адрес шлюза Istio с помощью: kubectl -n istio-system get svc. Нам необходимо убедиться, что доменное имя, указанное в host:, указывает на External IP шлюза Istio.

Внесение изменений в репозиторий production окружения будет автоматически триггерить сборку в Jenkins X, проверим через:


 jx get activity

Ждем пока все activities станут successful. Теперь нам нужно увидеть как автоматически создались Istio VirtualService и Gateway:


kubectl -n jx-production get virtualservices.networking.istio.io,gateways.networking.istio.io

Заметим, что в первый раз, когда он был задеплоен, он не выполнит сanary, так как ему нужна предыдущая версия приложения для сравнения, но он заработает после второго деплоя. (источник)

Теперь нам нужна возможность доступа к нашему приложению в production через Istio на определенном хосте:


jenkinsx-istio-canary-python-test.35.204.67.7.nip.io:




Откроем Flagger Grafana Dashboard


Flagger установит Grafana в namespace istio-system, следовательно, мы можем выполнить:


kubectl port-forward -n istio-system service/flagger-grafana 3000:80
# admin:admin




В Grafana перейдите в Istio Dashboard и введите:


  • namespace: jx-production
  • primary: jx-jenkinsx-istio-canary-python-test-primary
  • canary: jx-jenkinsx-istio-canary-python-test-canary

Primary и canary это названия services. Они созданы автоматически при деплое, когда Canary был включен.


Если у вас отсутствуют метрики istio_requests_total, убедитесь, что Istio установлена правильно, возможно, потребуется установка вручную, а не через jx.


Flagger Canary Workflow и Анализ


В Helm Chart для Python приложений у нас есть множество настроек, которые мы можем изменять (здесь можно почитать описания большинства из них):


canary:
 enabled: false # false, but we set to true in prod env git repo
 progressDeadlineSeconds: 60
 canaryAnalysis:
   interval: "1m"
   threshold: 5
   maxWeight: 60
   stepWeight: 20
   # WARNING: Canary deployments will fail and rollback if there is no traffic that will generate the below specified metrics.
   metrics:
     requestSuccessRate:
       threshold: 99
       interval: "1m"
     requestDuration:
       threshold: 1000
       interval: "1m"

Мы должны скорректировать их в зависимости от потребностей нашего приложения. Flagger выполнит автоматический анализ метрик и будет выполнять развертывание только при соблюдении требований.
Чтобы увидеть текущий статус развертывания Canary, проверьте ресурсы Flagger:


kubectl -n jx-production get canaries.flagger.app

Выполнение Canary Deployment


Deploy изменений


Сейчас мы изменили приложение app.py так, чтобы оно возвращало другой текст на GET запрос. Создаем Pull Request в master-репозитории с приложением и делаем его merge. Jenkins X выполнит его автоматический deploy на stage.


Теперь задеплоим его вручную на prod, скопируем новую версию, которая запущена на stage. Сейчас я на 0.0.6 версии, так как я внес некоторые изменения между ними:


jx promote --version 0.0.6 --env production

И можем посмотреть статус работы Canary:


kubectl -n jx-production get events --field-selector involvedObject.kind=Canary --sort-by='{.lastTimestamp}'

Запуск Canary с весом 20%


2m39s       Normal    Synced   Canary   Advance jx-jenkinsx-istio-canary-python-test.jx-production canary weight 20

Мы запускаем повторяющийся curl на production Istio endpoint, который выдает результат, что 20% запросов отправлены на новую версию:





Canary терпит неудачу (недостаточно трафика)


Мы должны убедиться, что достаточно трафика достигает endpoint, иначе Canary анализ через Flagger провалится и запустит откат:





Canary также не запустится, если соответственные требования не будут выполнены.


Canary с весом 40%


Если трафика, который успешно достигает приложения достаточно, Flagger увеличит вес до 40%:






Canary с весом 60%


Если будет достаточно трафика, которое смог быть корректно обработан, Flagger увеличит его объем до 60%:


60s         Normal    Synced   Canary   Advance jx-jenkinsx-istio-canary-python-test.jx-production canary weight 60




Canary прошел успешно


25s         Normal    Synced   Canary   Routing all traffic to primary

Теперь все запросы обрабатываются новой версией:





Итог


Jenkins X можно относительно легко настроить для работы с Istio и Flagger для Canary Deployments. Однако, у меня были проблемы с установкой Istio через jx create addon istio, и мне пришлось делать это вручную.


Я не игрался с настройками Flagger, но использование настроек просто по умолчанию, как мне кажется, отлично подходит для тестовых исследований. Я думаю, что как только вы познакомитесь с Jenkins X и с предлагаемым им функционалом, то сможете избавиться от множества ручной или повторяющейся работы.


Так же без Jenkins X, я думаю, сама по себе комбинация Flagger и Istio для Canary Deployments весьма мощна, относительно тех, которые я изучал самостоятельно в последнее время.


Ещё/Источники


https://jenkins-x.io/docs/managing-jx/tutorials/progressive-delivery/


https://docs.flagger.app/usage/progressive-delivery



(Прим. пер. — в конце статьи автор приводит ссылку на тренажер для подготовки к экзамену для получения сертификата CKAD — https://killer.sh/ )

Теги:
Хабы:
+7
Комментарии 0
Комментарии Комментировать

Публикации

Информация

Сайт
nixys.ru
Дата регистрации
Дата основания
Численность
51–100 человек
Местоположение
Россия
Представитель
Vlada Grishkina-Makareva