.NET Tutorial
Middle6 мин чтенияВопрос 6 из 10

Как реализовать blue-green и canary деплой?

Стратегии развёртывания

Rolling update

v1 v1 v1

v2 v1 v1

v2 v2 v1

v2 v2 v2

Blue-green

Blue v1: 100%
Green v2: 0% (проверка)

переключение

Green v2: 100%
Blue v1 — в резерве

Canary

v1: 100%

v2: 5%, v1: 95%
анализ метрик

v2: 25%

v2: 100%

Rolling update

v1 v1 v1

v2 v1 v1

v2 v2 v1

v2 v2 v2

Blue-green

Blue v1: 100%
Green v2: 0% (проверка)

переключение

Green v2: 100%
Blue v1 — в резерве

Canary

v1: 100%

v2: 5%, v1: 95%
анализ метрик

v2: 25%

v2: 100%

Три стратегии
Rolling Blue-green Canary
Трафик на новую версию Постепенно (по числу подов) 0% → 100% разом Контролируемая доля
Одновременная работа версий Да Коротко (или нет) Да, долго
Ресурсы +1 под (maxSurge) ×2 на время релиза Немного больше
Откат Постепенный (новая раскатка) Мгновенный Быстрый (доля → 0)
Проверка до трафика Только readiness Полная (smoke/e2e на green) На реальном трафике малой доли
Радиус поражения при баге Растёт с раскаткой 100% после переключения Минимальный
Сложность Встроено Средняя Выше: маршрутизация по весам, анализ метрик

Blue-green в Kubernetes

переключение

Пользователи

Service orders-api
selector: app=orders, color=blue

Deployment orders-blue
v1.4.1 (3 пода)

Deployment orders-green
v1.4.2 (3 пода)

Service orders-preview
для smoke/e2e тестов

kubectl patch service:
color = green

переключение

Пользователи

Service orders-api
selector: app=orders, color=blue

Deployment orders-blue
v1.4.1 (3 пода)

Deployment orders-green
v1.4.2 (3 пода)

Service orders-preview
для smoke/e2e тестов

kubectl patch service:
color = green

Переключение Service между двумя Deployment
Shell
# 1. Развернуть green рядом с blue
helm upgrade --install orders-green ./chart --set color=green --set image.tag=1.4.2
# 2. Проверить через preview-сервис
./smoke-tests.sh http://orders-preview.shop.svc
# 3. Переключить трафик
kubectl patch service orders-api -p '{"spec":{"selector":{"app":"orders","color":"green"}}}'
# 4. Откат (если нужно) — вернуть selector на blue; blue удаляют после периода наблюдения

В Azure App Service — deployment slots: развернуть в слот staging, прогреть, swap со слотом production.

Canary с Argo Rollouts

rollout.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata: { name: orders-api }
spec:
  replicas: 10
  selector: { matchLabels: { app: orders-api } }
  template: { ... }                                   # как в Deployment
  strategy:
    canary:
      canaryService: orders-api-canary
      stableService: orders-api-stable
      trafficRouting:
        nginx: { stableIngress: orders-api }            # или istio / Gateway API
      steps:
        - setWeight: 5
        - pause: { duration: 10m }
        - analysis: { templates: [ { templateName: error-rate } ] }
        - setWeight: 25
        - pause: { duration: 10m }
        - analysis: { templates: [ { templateName: error-rate } ] }
        - setWeight: 50
        - pause: { duration: 10m }
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata: { name: error-rate }
spec:
  metrics:
    - name: error-rate
      interval: 1m
      failureLimit: 2
      successCondition: result[0] < 0.01             # < 1% ошибок 5xx
      provider:
        prometheus:
          address: http://prometheus:9090
          query: |
            sum(rate(http_server_request_duration_seconds_count{service="orders-api-canary",http_response_status_code=~"5.."}[2m]))
            / sum(rate(http_server_request_duration_seconds_count{service="orders-api-canary"}[2m]))
PrometheusIngress (веса)Argo Rolloutsрелиз помеченDegraded, командаполучает алертcanary 5%анализ: error rate, p990.2% ошибок — OKcanary 25%анализ4% ошибок — превышен порогcanary 0% —автоматический откат
PrometheusIngress (веса)Argo Rolloutsрелиз помеченDegraded, командаполучает алертcanary 5%анализ: error rate, p990.2% ошибок — OKcanary 25%анализ4% ошибок — превышен порогcanary 0% —автоматический откат
Автоматический canary с анализом метрик

Что сравнивать на canary: долю 5xx, латентность p95/p99, насыщение (CPU, память), бизнес-метрики (конверсия оформления заказа, число оплат). Для честного сравнения — canary против baseline той же численности.

Условия безопасного релиза

v1 и v2 работают одновременно
(rolling, canary, откат)

Схема БД совместима с обеими:
expand → код → contract

API обратно совместим:
новые поля опциональны, старые не удаляются

Сообщения: v2 понимает формат v1 и наоборот

Кэш: ключи версионированы
или формат совместим

Sticky-сессии / Data Protection keys
общие для версий

v1 и v2 работают одновременно
(rolling, canary, откат)

Схема БД совместима с обеими:
expand → код → contract

API обратно совместим:
новые поля опциональны, старые не удаляются

Сообщения: v2 понимает формат v1 и наоборот

Кэш: ключи версионированы
или формат совместим

Sticky-сессии / Data Protection keys
общие для версий

Совместимость версий при одновременной работе
  • Миграции — expand/contract: добавить столбец (nullable) → выкатить код, пишущий в оба → перевести чтение → удалить старое следующим релизом.
  • Откат приложения ≠ откат БД: новая версия схемы должна поддерживать старую версию кода.
  • Наблюдаемость: метрики и трассировки с тегом версии (service.version) — чтобы видеть разницу canary vs stable.

Feature flags

Microsoft.FeatureManagement
builder.Services.AddFeatureManagement();

app.MapPost("/checkout", async (IFeatureManager features, CheckoutRequest req) =>
    await features.IsEnabledAsync("NewCheckout")
        ? await newCheckout.HandleAsync(req)
        : await oldCheckout.HandleAsync(req));
appsettings.json — постепенное включение
{
  "FeatureManagement": {
    "NewCheckout": {
      "EnabledFor": [ { "Name": "Microsoft.Percentage", "Parameters": { "Value": 10 } } ]
    }
  }
}

Флаги позволяют деплоить код «выключенным», включать функцию для процента пользователей, тестировщиков или региона и мгновенно выключать без деплоя. Важно удалять флаги после завершения раскатки — иначе накапливается технический долг.

Вопросы на засыпку

Чем canary отличается от A/B-тестирования?

Canary проверяет техническое качество новой версии (ошибки, производительность) и стремится к 100%. A/B-тест сравнивает бизнес-эффект двух вариантов функции (конверсия) на разных сегментах пользователей, часто долго и с продуктовым анализом. Технически оба используют разделение трафика и feature flags.

Как в blue-green поступить с базой данных?

Обычно БД общая для blue и green, поэтому изменения схемы должны быть совместимы с обеими версиями (expand/contract). Две отдельные БД с синхронизацией — сложно и редко оправдано.

Почему rolling update не всегда безопасен?

Во время раскатки часть запросов обслуживает v1, часть — v2; пользователь может попасть на разные версии в соседних запросах. Если v2 несовместима (API, формат сессии, схема), возникают ошибки. Кроме того, баг затрагивает всё больше пользователей по мере раскатки без автоматической проверки метрик.

Что такое progressive delivery?

Общее название подходов, при которых изменения доставляются постепенно с автоматической проверкой: canary с анализом метрик, feature flags с процентным включением, blue-green с проверками, автоматический откат. Инструменты — Argo Rollouts, Flagger, LaunchDarkly/Unleash.

Итог

Rolling update — стратегия по умолчанию, blue-green даёт полную проверку до переключения и мгновенный откат ценой двойных ресурсов, canary минимизирует радиус поражения постепенной раскаткой с анализом метрик. Любая стратегия требует совместимости версий (БД, API, сообщения) и наблюдаемости, а feature flags отделяют деплой от включения функциональности.