Blue-Green и Canary деплой
Blue-Green и Canary деплой
1) Задача и ключевые идеи
Blue-Green и Canary — стратегии безостановочных релизов, уменьшающие риск внедрения:- Blue-Green: держим две параллельные версии (Blue — активная, Green — новая), переключаем трафик атомарно. Быстрый откат → мгновенно вернуть Blue.
- Canary: включаем новую версию поэтапно (1% → 5% → 25% → 50% → 100%), мониторим SLO-метрики и останавливаем/откатываем при деградации.
Общий принцип: отделить «доставку артефакта» от «включения трафика» и автоматизировать наблюдаемость + откаты.
2) Когда что выбирать
Blue-Green подходит, когда:- нужно мгновенное переключение (жесткие RTO), простые state-less сервисы;
- есть строгие окна релиза/заморозки и понятные проверки smoke;
- дорого держать длительную двойную емкость — но кратковременно можно.
- сложные изменения, требуется поэтапная валидация на реальном трафике;
- есть зрелая телеметрия (SLO, бизнес-метрики), возможность авто-стопа;
- критично ограничить радиус поражения (финтех/iGaming-потоки).
Комбо-паттерн: выкатывать Green и переключаться на него через canary-ступени (Blue-Green как каркас, Canary как метод переноса трафика).
3) Архитектура маршрутизации трафика
Варианты переключения/доливки трафика:1. L4/L7-балансировщик (ALB/NLB, Cloud Load Balancer) — взвешенные target groups.
2. API-шлюз/WAF — route/weight по версиям, заголовкам, cookie, регионам.
3. Service Mesh (Istio/Linkerd/Consul) — процентное распределение, fault-инъекция, ручки таймаутов/ретраев/ограничения.
4. Ingress/NGINX/Envoy — upstream-веса и маршрутизация по атрибутам.
5. Argo Rollouts/Flagger — оператор-контроллер, автоматическая прогрессия, интеграция с Prometheus/New Relic/Datadog.
4) Kubernetes: практические шаблоны
4.1 Blue-Green (через Service selector)
Два Deployment: `app-blue` и `app-green`.
Один Service `app-svc` с селектором на нужный `version`.
yaml apiVersion: apps/v1 kind: Deployment metadata: { name: app-green, labels: { app: app, version: green } }
spec:
replicas: 4 selector: { matchLabels: { app: app, version: green } }
template:
metadata: { labels: { app: app, version: green } }
spec:
containers:
- name: app image: ghcr. io/org/app:1. 8. 0 apiVersion: v1 kind: Service metadata: { name: app-svc }
spec:
selector: {app: app, version: blue} # ← switch to green - change ports: [{port: 80, targetPort: 8080}]
Переключение — атомарная смена селектора (или меток) с контролируемым drain.
4.2 Canary (Istio VirtualService)
yaml apiVersion: networking. istio. io/v1beta1 kind: VirtualService metadata: { name: app }
spec:
hosts: ["app. example. com"]
http:
- route:
- destination: { host: app. blue. svc. cluster. local, subset: v1 }
weight: 90
- destination: { host: app. green. svc. cluster. local, subset: v2 }
weight: 10
Меняйте `weight` по ступеням; добавьте retry, timeout, outlier-detector на DestinationRule.
4.3 Argo Rollouts (авто-канареечный прогон)
yaml apiVersion: argoproj. io/v1alpha1 kind: Rollout metadata: { name: app }
spec:
replicas: 6 strategy:
canary:
canaryService: app-canary stableService: app-stable steps:
- setWeight: 5
- pause: {duration: 300} # 5 min observation
- analysis:
templates:
- templateName: slo-guard
- setWeight: 25
- pause: { duration: 600 }
- analysis:
templates: [{ templateName: slo-guard }]
- setWeight: 50
- pause: {}
trafficRouting:
istio:
virtualService:
name: app routes: ["http-route"]
Анализ-шаблон связан с метриками (см. ниже).
5) SLO-гейты и авто-откат
Охраняемые метрики (примеры):- Технические: `p95_latency`, `5xx_rate`, `error_budget_burn`, `CPU/Memory throttling`.
- Продуктовые: `CR(депозит)`, `успех выплат`, `скоринг-фрода`, `ARPPU` (на холодных окнах).
- Если `5xx_rate` новой версии > 0.5% в течение 10 мин — pause и rollback.
- Если `p95_latency` ↑ > 20% от базовой — rollback.
- Если промоушен канареек идет, но SLO бюджета сжигается > 2%/час — hold.
yaml apiVersion: argoproj. io/v1alpha1 kind: AnalysisTemplate metadata: { name: slo-guard }
spec:
metrics:
- name: http_5xx_rate interval: 1m successCondition: result < 0. 005 provider:
prometheus:
address: http://prometheus. monitoring:9090 query:
sum(rate(http_requests_total{app="app",status=~"5.."}[5m])) /
sum(rate(http_requests_total{app="app"}[5m]))
6) Данные и совместимость (самая частая причина боли)
Используйте стратегию expand → migrate → contract:- Expand: добавить новые nullable-колонки/индексы, поддержать обе схемы.
- Migrate: двойная запись/чтение, бэк-филл.
- Contract: удалить старые поля/код после выхода на 100% трафика.
- Событийные/очереди: версионируйте payload (v1/v2), поддерживайте idempotency.
- Кэш/сессии: версионируйте ключи; обеспечьте совместимость формата.
7) Интеграция с CI/CD и GitOps
CI: сборка единого артефакта (build once), подпись образа, SBOM, тесты.
CD: промоушен артефакта через окружения; Blue-Green/Canary управляются манифестами.
GitOps: мерж MR → контроллер (Argo CD/Flux) применяет веса/селектора.
Environments/Approvals: для прод-степов — ручной gate + аудит решений.
8) NGINX/Envoy и облачные LB: быстрые примеры
8.1 NGINX (веса апстримов)
nginx upstream app_upstream {
server app-blue:8080 weight=90;
server app-green:8080 weight=10;
}
server {
location / { proxy_pass http://app_upstream; }
}
8.2 AWS ALB (Weighted Target Groups)
TG-Blue: 90, TG-Green: 10 → меняйте веса через IaC/CLI.
Привяжите CloudWatch-алерты к автo-скриптам rollback (смена веса на 0/100).
9) Безопасность и соответствие
Zero trust между версиями: разграничьте секреты/роллинг-ключи шифрования.
Policy-as-Code: запрет деплоя неподписанных образов, `no latest`.
Секреты и конфиги как артефакты версий; откат включает откат конфигов.
Аудит: кто, когда поднял вес/переключил селектор, с каким тикетом.
10) Стоимость и емкость
Blue-Green требует двойной мощности на период релиза → планируйте окно.
Canary может тянуться дольше → стоимость телеметрии/наблюдения, параллельное содержание двух версий.
Оптимизация: autoscaling по HPA/VPA, короткие окна Blue-Green, ночные релизы для «тяжелых» сервисов.
11) Откаты (runbook)
1. Заморозить продвижение (pause).
2. Снизить вес Green до 0% (canary) / вернуть селектор на Blue (blue-green).
3. Проверить: ошибки/латентность вернулись к базовым, дренировать соединения.
4. Открыть инцидент, собрать артефакты (логи, трассы, сравнение метрик).
5. Фикс/репрод в stage, прогнать smoke, перезапустить прогрессию.
12) Анти-паттерны
Пересборка артефакта между stage и prod (нарушение «build once»).
«Глухой» canary без SLO/метрик — формальность, а не защита.
Отсутствие фича-флагов: релиз вынужден включать поведение сразу на 100%.
Неработающие health-checks/liveness → «залипшие» поды и ложная стабильность.
Совместимость БД «на авось»: контракт ломается при переключении.
Мутабельные теги образов / `latest` в проде.
13) Чек-лист внедрения (0–45 дней)
0–10 дней
Выбрать стратегию для сервисов: B/G, Canary или комбинированно.
Включить подписание образов, health-checks, readiness-пробы, `no latest`.
Подготовить дашборды SLO (latency/error rate/бизнес-метрики).
11–25 дней
Автоматизировать веса (Istio/Argo Rollouts/ALB-weights).
Настроить analysis templates, алерты и авто-rollback.
Шаблонизировать манифесты (Helm/Kustomize), интегрировать с GitOps.
26–45 дней
Внедрить стратегию expand-migrate-contract для БД.
Покрыть критические флоу kill-switch флагами.
Провести «game day»: симулировать откат и инцидент.
14) Метрики зрелости
% релизов через Blue-Green/Canary (цель > 90%).
Среднее время переключения/отката (цель < 3 мин).
Доля релизов с автo-стопом по SLO (и без инцидентов).
Покрытие сервисов телеметрией (traces/logs/metrics) > 95%.
Доля миграций БД по схеме expand-migrate-contract > 90%.
15) Приложения: шаблоны политик и пайплайнов
OPA (запрет неподписанных образов)
rego package admission. image
deny[msg] {
input. request. kind. kind == "Deployment"
some c img:= input. request. object. spec. template. spec. containers[c].image not startswith(img, "ghcr. io/org/")
msg:= sprintf("Image not from trusted registry: %v", [img])
}
Helm-values для canary (упрощенно)
yaml canary:
enabled: true steps:
- weight: 5 pause: 300
- weight: 25 pause: 600
- weight: 50 pause: 900 sloGuards:
max5xxPct: 0. 5 maxP95IncreasePct: 20
GitHub Actions — промоушен веса (псевдо)
yaml
- name: Promote canary to 25%
run: kubectl patch virtualservice app \
--type=json \
-p='[{"op":"replace","path":"/spec/http/0/route/1/weight","value":25}]'
16) Заключение
Blue-Green и Canary — не взаимоисключающие, а комплементарные стратегии. Стройте их поверх подписанных артефактов, наблюдаемости по SLO, автоматических гейтов и GitOps-управления. Отделяйте доставку от включения, держите быстрый откат и дисциплину миграций — и релизы станут предсказуемыми, безопасными и быстрыми.