Автоматизация решений о Canary Release в вашем Kubernetes-кластере
December 30, 2022
Предыстория
В настоящее время микросервисы стали типичной и широко используемой архитектурной моделью программного обеспечения. Сервисы слабо связаны и взаимодействуют через 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 необходимо развернуть 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 и контроллера канареечного выпуска.
- Подготовьте доступный кластер Kubernetes, если хотите выполнить следующие команды.
- Контроллеру канареечного выпуска необходим токен доступа для вызова 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.