Canary Deployment в Kubernetes #2: Argo Rollouts

Ми будемо використовувати k8s-нативний контролер розгортання Argo Rollouts та GitlabCI для запуску Canary деплою у Kubernetes

Canary Deployment в Kubernetes #2: Argo Rollouts

https://unsplash.com/photos/V41PulGL1z0

Статті цього циклу

Канарське розгортання

Сподіваємось, що Ви читали першу частину, де ми коротко пояснювали, що таке Canary Deployments. Ми також показували як його реалізувати використовуючи стандартні ресурси Kubernetes.

Argo Rollouts

Argo Rollouts – це Kubernetes-нативний контролер розгортання. Він надає CRD (Custom Resource Definition) для Kubernetes. Завдяки йому ми можемо використовувати нову сутність: Rolloutяка управляє blue-green і сanary deployments з різними варіантами налаштування.

Контролер Argo Rollouts, що використовується кастомним ресурсом Rollout, дозволяє використовувати додаткові стратегії розгортання, такі як blue-green та сanary для Kubernetes. Ресурс Rollout надає функціонал рівнозначний Deploymentтільки з додатковими стратегіями розгортання.
ресурс Deployments має дві стратегії для розгортання: RollingUpdate и Recreate. Незважаючи на те, що ці стратегії підходять для більшості випадків, для деплою на сервері в дуже великому масштабі використовують додаткові стратегії, такі як blue-green або canary, яких немає в Deployment контролері. Щоб використовувати ці стратегії в Kubernetes, користувачам доводилося писати скрипти поверх своїх Deployments. Контролер Argo Rollouts надає ці стратегії у вигляді простих декларативних параметрів, що настроюються.
https://argoproj.github.io/argo-rollouts

Існує також Argo CI, який надає зручний веб-інтерфейс для використання разом із Rollouts, ми поглянемо на нього у наступній статті.

Установка Argo Rollouts

На стороні сервера

kubectl create namespace argo-rolloutskubectl apply -n argo-rollouts -f https://raw.githubusercontent.com/argoproj/argo-rollouts/stable/manifests/install.yaml

У нашій інфраструктурній ріпі (див. нижче) ми вже додали install.yaml як i/k8s/argo-rollouts/install.yaml. Таким чином, GitlabCI встановить його в кластер.

На стороні клієнта (kubectl plugin)

https://argoproj.github.io/argo-rollouts/features/kubectl-plugin

Додаток для прикладу

Хорошою практикою є наявність окремих репозиторіїв для коду програми та інфраструктури.

Репозиторій для програми

Kim Wuestkamp/k8s-deployment-example-app

Це дуже проста API на Python+Flask, що повертає відповідь у вигляді JSON. Ми зберемо пакет, використовуючи GitlabCI і запустимо результат у Gitlab Registry. У регістрі у нас є дві різні версії релізів:

  • wuestkamp/k8s-deployment-example-app:v1
  • wuestkamp/k8s-deployment-example-app:v2

Єдина різниця між ними це JSON-файл, що повертається. Ми використовуємо цю програму для максимально простої візуалізації того, з якою версією ми спілкуємося.

Інфраструктурний репозиторій

У цьому репозиторії ми будемо використовувати GitlabCI для деплою в Kubernetes, .gitlab-ci.yml виглядає так:

image: traherom/kustomize-dockerbefore_script:
   - printenv
   - kubectl versionstages:
 - deploydeploy test:
   stage: deploy
   before_script:
     - echo $KUBECONFIG
   script:
     - kubectl get all
     - kubectl apply -f i/k8s    only:
     - master

Для його запуску самостійно вам знадобиться кластер, можна використовувати Gcloud:

gcloud container clusters create canary --num-nodes 3 --zone europe-west3-b
gcloud compute firewall-rules create incoming-80 --allow tcp:80

Вам потрібно зробити форк https://gitlab.com/wuestkamp/k8s-deployment-example-canary-infrastructure та створити змінну KUBECONFIG у GitlabCI, яка міститиме конфіг для доступу kubectl до вашого кластера.

Тут можна прочитати про те, як отримати облікові дані для кластера (Gcloud).

Інфраструктурний Yaml

Всередині інфраструктурного репозиторію ми маємо service:

apiVersion: v1
kind: Service
metadata:
 labels:
   id: rollout-canary
 name: app
spec:
 ports:
 - port: 80
   protocol: TCP
   targetPort: 5000
 selector:
   id: app
 type: LoadBalancer

і rollout.yaml :

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
 name: rollout-canary
spec:
 replicas: 10
 revisionHistoryLimit: 2
 selector:
   matchLabels:
     id: rollout-canary
 template:
   metadata:
     labels:
       id: rollout-canary
   spec:
     containers:
     - name: rollouts-demo
       image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v1
       imagePullPolicy: Always
 strategy:
   canary:
     steps:
     - setWeight: 10
     # Rollouts can be manually resumed by running `kubectl argo rollouts promote ROLLOUT`
     - pause: {}
     - setWeight: 50
     - pause: { duration: 120 } # two minutes

Rollout працює так само, як і Deployment. Якщо ми не поставимо стратегію оновлення (як canary тут) він буде поводитися як дефолтний rolling-update Deployment.

Ми визначаємо два кроки у yaml для canary deployment:

  1. 10% трафіку на canary (wait for manual OK)
  2. 50% трафіку на canary (wait 2 minutes then continue to 100%)

Виконання початкового деплою

Після початкового деплою наші ресурси виглядатимуть так:

Canary Deployment в Kubernetes #2: Argo Rollouts

І отримуємо відповідь тільки від першої версії програми:

Canary Deployment в Kubernetes #2: Argo Rollouts

Виконуємо Canary Deployment

Крок 1: 10% трафіку

Щоб почати canary розгортання, нам просто потрібно змінити версію образу, як ми зазвичай робимо з розгортаннями:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
 name: rollout-canary
spec:
...
 template:
   metadata:
     labels:
       id: rollout-canary
   spec:
     containers:
     - name: rollouts-demo
       image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
...

І ми пушимо зміни, тому Gitlab CI робить deploy і ми бачимо зміни:

Canary Deployment в Kubernetes #2: Argo Rollouts

Зараз якщо ми звернемося до сервісу:

Canary Deployment в Kubernetes #2: Argo Rollouts

Чудово! Ми є у середині нашого canary deployment. Ми можемо побачити прогрес, запустивши:

kubectl argo rollouts get rollout rollout-canary

Canary Deployment в Kubernetes #2: Argo Rollouts

Крок 2: 50% трафіку:

Тепер приступаємо до наступного кроку: перенаправлення 50% трафіку. Ми налаштували так, щоб цей крок було запущено вручну:

kubectl argo rollouts promote rollout-canary # continue to step 2

Canary Deployment в Kubernetes #2: Argo Rollouts

І наш додаток повернув 50% відповідей від нових версій:

Canary Deployment в Kubernetes #2: Argo Rollouts

І огляд rollout:

Canary Deployment в Kubernetes #2: Argo Rollouts

Чудово.

Крок 3: 100% трафіку:

Ми налаштували так, щоб через 2 хвилини крок із 50% завершувався автоматично та запускався крок зі 100%:

Canary Deployment в Kubernetes #2: Argo Rollouts

І висновок програми:

Canary Deployment в Kubernetes #2: Argo Rollouts

І огляд rollout:

Canary Deployment в Kubernetes #2: Argo Rollouts

Canary деплою завершено.

Ще приклади з Argo Rollouts

Тут є ще приклади, наприклад, як налаштувати попередній перегляд оточення та порівняння, засновані на canary:

https://github.com/argoproj/argo-rollouts/tree/master/examples

Відео про Argo Rollouts та Argo CI

Я дійсно рекомендую це відео, у ньому показується як Argo Rollouts та Argo CI працюють разом:

Підсумок

Мені дуже подобається ідея використання CRDs, які керують створенням додаткових типів deployments або replicasets, перенаправляють трафік ітд. Робота з ними відбувається гладко. Далі мені хотілося б протестувати інтеграцію з Argo CI.

Однак, зважаючи на все, наближається велике злиття Argo CI і Flux CI, так що я міг би почекати, поки не вийде новий реліз: Argo Flux.

А чи був у Вас досвід з Argo Rollouts чи Argo CI?

Також читайте інші статті у нашому блозі:

Джерело: habr.com

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