Автоматизация решений о Canary Release в вашем Kubernetes-кластере

Chao Zhang

Chao Zhang

December 30, 2022

Technology

Предыстория

В настоящее время микросервисы стали типичной и широко используемой архитектурной моделью программного обеспечения. Сервисы слабо связаны и взаимодействуют через API. Микросервисная модель позволяет каждому приложению быть независимо развертываемым и поддерживаемым, что делает выпуски более частыми. Как известно, выпуск новых версий сопряжен с рисками; никогда нельзя быть уверенным, что в новой версии нет ошибок. Именно поэтому люди используют стратегии, такие как канареечный выпуск (canary release) и сине-зеленое развертывание (blue-green deployment), чтобы постепенно внедрять новую версию и снижать риски.

Канареечный выпуск разделяет трафик на две группы целевого сервиса: стабильную группу и канареечную. API Gateway, такой как Apache APISIX, эффективно и безопасно предоставляет микросервисную архитектуру через API. Он оснащен функцией канареечного выпуска. Обычно существует два способа разделения трафика: на основе веса и на основе предикатных выражений.

Способ на основе веса

Способ на основе веса

Пользователям необходимо указать долю трафика, которая будет направлена в канареечную группу. На изображении выше 95% трафика будет направлено на стабильный сервис, а остальные 5% — на канареечный.

Способ на основе предикатных выражений

Способ на основе предикатов

Способ на основе предикатных выражений указывает, что только трафик, соответствующий заданным характеристикам, будет направлен в канареечную группу. Например, только HTTP-запросы с заголовком X-Debug и его фактическим значением достигнут канареечного сервиса.

Автоматизация канареечного выпуска

Когда вы управляете API Gateway через вызов API или через панель управления, может возникать задержка в настройке соотношения трафика (для способа на основе веса) или предикатов (для способа на основе предикатных выражений). В настоящее время все больше пользователей используют Kubernetes для оркестрации своих микросервисов. Можно ли начать канареечный выпуск сразу после создания новой версии сервиса? В этой статье я покажу, как использовать API7 Cloud для автоматизации канареечного выпуска в вашем кластере Kubernetes.

Что такое API7 Cloud

API7 Cloud — это мультиоблачная SaaS-платформа для развертывания, управления, визуализации и мониторинга API в масштабе. Запускайте свои API где угодно, но управляйте ими в одном месте. API7 Cloud использует Apache APISIX в качестве API Gateway для эффективного и безопасного предоставления ваших API.

API7 Cloud

Для использования API7 Cloud необходимо развернуть Apache APISIX на вашей инфраструктуре, например, в Docker или Kubernetes. Вы можете использовать Cloud CLI для упрощения развертывания.

# Настройте токен доступа из консоли API7 Cloud. cloud-cli configure --token {YOUR TOKEN} # Разверните Apache APISIX (версия 2.15.1) в пространстве имен apisix с одной репликой. cloud-cli deploy kubernetes \ --name my-apisix \ --namespace apisix \ --replica-count 1 \ --apisix-image apache/apisix:2.15.1-centos

Канареечный выпуск — одна из встроенных функций API7 Cloud. Пользователи могут настраивать правила канареечного выпуска через консоль или вызывать API7 Cloud Open API. Наша цель — автоматизировать принятие решений о канареечном выпуске, поэтому мы будем использовать второй способ.

Сценарий

Предположим, что в нашем кластере Kubernetes есть простое приложение error-page, которое всегда возвращает сообщение об ошибке. Мы выпускаем версию 2.0 и хотим использовать стратегию канареечного выпуска, чтобы снизить риски. Более того, мы хотим автоматизировать весь процесс. Поэтому мы создаем контроллер канареечного выпуска, который отслеживает изменения в ресурсах сервисов Kubernetes, а затем создает/изменяет канареечные выпуски в API7 Cloud через API7 Cloud Go SDK. Мы будем использовать только способ на основе веса для разделения трафика. Все компоненты, включая API Gateway Apache APISIX, будут развернуты в Kubernetes, поэтому схема будет выглядеть следующим образом:

Схема

Контроллер канареечного выпуска отслеживает изменения в сервисах и реагирует на них в соответствии с некоторыми аннотациями, а именно:

  • Если сервис содержит аннотацию api7.cloud/published-service, контроллер канареечного выпуска попытается создать приложение в API7 Cloud.
  • Если сервис имеет аннотацию api7.cloud/published-canary-service, контроллер канареечного выпуска попытается настроить правило канареечного выпуска в API7 Cloud, и аннотация api7.cloud/published-service-canary-percentage определит процент.

Обратите внимание, что этот контроллер не является самодостаточным (он не удаляет приложение, если сервис удален), но его достаточно для демонстрации автоматизированного процесса канареечного выпуска.

Поехали!

Начнем с развертывания Apache APISIX и контроллера канареечного выпуска. Как упоминалось выше, мы используем Cloud CLI для развертывания Apache APISIX. У нас также есть два YAML-файла (error-page/manifest-v1.yaml и controller/manifest.yaml) для развертывания приложения error-page и контроллера канареечного выпуска.

  1. Подготовьте доступный кластер Kubernetes, если хотите выполнить следующие команды.
  2. Контроллеру канареечного выпуска необходим токен доступа для вызова API API7 Cloud. Мы получаем токен в соответствии с этой документацией и сохраняем его в секрете Kubernetes.
kubectl create namespace canary-release-demo # Разверните версию v1 приложения error-page. kubectl apply -f https://raw.githubusercontent.com/tokers/canary-release-automation-demo/main/error-page/manifest-v1.yaml -n canary-release-demo # Создайте секрет Kubernetes для сохранения токена доступа API7 Cloud. kubectl create secret generic api7-cloud --namespace canary-release-demo --from-literal token={Your Access Token} # Разверните контроллер канареечного выпуска. kubectl apply -f https://raw.githubusercontent.com/tokers/canary-release-automation-demo/main/controller/manifest.yaml -n canary-release-demo # Проверьте, все ли рабочие нагрузки работают нормально. kubectl get all -n canary-release-demo

Проверка прокси

Давайте опубликуем этот сервис, добавив аннотацию.

kubectl annotate service -n canary-release-demo error-page-v1 "api7.cloud/published-service=error-page"

Контроллер канареечного выпуска отследит это изменение и создаст приложение в API7 Cloud. Теперь давайте обратимся к Apache APISIX, чтобы проверить, работает ли прокси нормально.

kubectl port-forward -n canary-release-demo service/apisix-gateway 10080:80 curl http://127.0.0.1:10080/api/error_page -H 'Host: error-page' -s

Если все в порядке, вы увидите {"error": "injected by error_page service", "version": "v1"}.

В настоящее время контроллер канареечного выпуска создает API "match-everything" в приложении, и Host совпадает с именем приложения (error-page).

Выпуск версии V2

Мы хотим выпустить версию 2 для приложения error-page. Сначала мы развернем версию 2, применив manifest-v2.yaml. Мы добавляем аннотации канареечного выпуска к сервису error-page-v2.

kubectl apply -f https://raw.githubusercontent.com/tokers/canary-release-automation-demo/main/error-page/manifest-v2.yaml -n canary-release-demo # Сообщите контроллеру канареечного выпуска, что мы включаем канареечный выпуск для error-page-v2, и процент составляет 10%. kubectl annotate service -n canary-release-demo error-page-v2 "api7.cloud/published-canary-service=true" "api7.cloud/published-service-canary-percentage=10" # Запустите канареечный выпуск. kubectl annotate service -n canary-release-demo error-page-v2 "api7.cloud/published-service=error-page"

Теперь давайте отправим 100 запросов к Apache APISIX снова и посмотрим, были ли некоторые запросы перенаправлены на канареечный сервис error-page-v2.

kubectl port-forward -n canary-release-demo service/apisix-gateway 10080:80 for ((i=0; i<100; i++)); do curl http://127.0.0.1:10080/api/error_page -H 'Host: error-page' -s done

Если все в порядке, около 10% запросов достигнут error-page-v2 (не точно 10% из-за внутренней стратегии выбора бэкенда Apache APISIX).

Откат

Мы обнаружили, что версия 2 нестабильна, и хотим откатить ее. Прежде чем сделать это, мы остановим канареечный выпуск, установив процент на 0. Затем снова отправим запросы к Apache APISIX.

kubectl annotate service -n canary-release-demo error-page-v2 "api7.cloud/published-service-canary-percentage=0" --overwrite for ((i=0; i<100; i++)); do curl http://127.0.0.1:10080/api/error_page -H 'Host: error-page' -s done

Теперь все запросы будут направлены на error-page-v1.

Выпуск

Через некоторое время мы убедились, что версия 2 достаточно стабильна, и хотим, чтобы все запросы достигали версии 2. Затем мы можем вывести из эксплуатации версию 1 приложения error-page. Для этого мы устанавливаем процент на 100%.

kubectl annotate service -n canary-release-demo error-page-v2 "api7.cloud/published-service-canary-percentage=100" --overwrite for ((i=0; i<100; i++)); do curl http://127.0.0.1:10080/api/error_page -H 'Host: error-page' -s done

Теперь все запросы перенаправляются на error-page-v2. И error-page-v1 можно безопасно вывести из эксплуатации.

Итог

Канареечный выпуск — это эффективный инструмент для выпуска новых версий. Однако настройка стратегии канареечного выпуска может быть запаздывающей. В этой статье показано, как управлять канареечными выпусками декларативно и автоматизировать процесс канареечного выпуска до определенной степени. Некоторые могут стремиться к полностью автоматическому канареечному выпуску с помощью компонентов GitOps. Например, используя Argo Rollouts, можно автоматически продвигать или откатывать сервисы. Argo Rollouts запрашивает метрики сервисов и интегрируется с контроллерами ingress для изменения их CRD. В конечном итоге API Gateway будет перенаправлять запросы в правильных пропорциях на канареечную версию.

Ссылки

Исходный код для приложения error-page и контроллера канареечного выпуска: https://github.com/tokers/canary-release-automation-demo.

Tags: