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

Статьи этого цикла
- (Эта статья)
- Canary Deployment using Istio
- Canary Deployment using Jenkins-X Istio Flagger
Canary Deployment
Надеемся, что Вы читали , где мы кратко объясняли что такое 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 предоставляет эти стратегии в виде простых декларативных настраиваемых параметров.
Существует также 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)
Приложение для примера
Хорошей практикой является наличие отдельных репозиториев для кода приложения и для инфраструктуры.
Репозиторий для приложения
Это очень простая 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Вам нужно сделать форк и создать переменную 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 minutesRollout работает так же как и Deployment. Если мы не зададим стратегию обновления (как canary здесь) он будет вести себя как дефолтный rolling-update Deployment.
Мы определяем два шага в yaml для canary deployment:
- 10% трафика на canary (wait for manual OK)
- 50% трафика на canary (wait 2 minutes then continue to 100%)
Выполнение начального деплоя
После начального деплоя наши ресурсы будут выглядеть так:

И получаем ответ только от первой версии приложения:

Выполняем 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. Мы можем увидеть прогресс, запустив:
kubectl argo rollouts get rollout rollout-canary

Шаг 2: 50% трафика:
Теперь приступаем к следующему шагу: перенаправление 50% трафика. Мы настроили так, чтобы этот шаг был запущен вручную:
kubectl argo rollouts promote rollout-canary # continue to step 2

И наше приложение вернуло 50% ответов от новых версий:

И обзор rollout:

Прекрасно.
Шаг 3: 100% трафика:
Мы настроили так, чтобы спустя 2 минуты шаг с 50% завершался автоматически и запускался шаг со 100%:

И вывод приложения:

И обзор rollout:

Canary деплой завершен.
Ещё примеры с Argo Rollouts
Здесь есть ещё примеры, например, как настроить предварительный просмотр окружения и сравнения, основанные на canary:
Видео об Argo Rollouts и Argo CI
Я действительно рекомендую это видео, в нем показывается как Argo Rollouts и Argo CI работают вместе:

Итог
Мне очень нравится идея использования CRDs, которые управляют созданием дополнительных типов deployments или replicasets, перенаправляют трафик итд. Работа с ними проходит гладко. Далее мне бы хотелось протестировать интеграцию с Argo CI.
Однако, судя по всему, грядет большое слияние Argo CI и Flux CI, так что я мог бы подождать, пока не выйдет новый релиз: .
А был ли у Вас опыт с Argo Rollouts или Argo CI?
Также читайте другие статьи в нашем блоге:
Источник: habr.com
