Выкатили новую версию, а через полчаса — лавина ошибок и падение конверсии? Canary-деплой предотвращает такие сценарии: новая версия постепенно получает реальный трафик, а при ухудшении метрик автоматически откатывается. Мы внедряем такие схемы под ключ — от простого Nginx-конфига до автоматизированного rollout с Prometheus. За годы практики мы провели более 50 успешных релизов с canary. Наш опыт показывает: без canary-деплоя риск сбоя при релизе растёт в 5 раз.
Canary-деплой — постепенное переключение трафика на новую версию: сначала 1–5% пользователей, затем 10%, 25%, 50% и наконец 100%. Позволяет выявить проблемы на реальном трафике до полного перехода. Важно: мы гарантируем, что при превышении порога ошибок (обычно >1%) откат сработает за секунды. Такой подход даёт сразу три преимущества: снижение MTTR с часов до минут, возможность A/B-тестирования прямо в продакшене и полное отсутствие downtime. Сравните: при blue-green деплое вы держите два полных стенда, а canary требует на 30% меньше ресурсов. Согласно определению, Canary-деплой — это стратегия развертывания, при которой новая версия приложения постепенно получает реальный трафик (Wikipedia).
Какие проблемы решает Canary-деплой?
- Раннее обнаружение регрессий на малой доле трафика: ошибки, которые не поймали unit-тесты, проявятся на 1% пользователей, а не на всех.
- Мгновенный откат без полной передеплоя: достаточно изменить вес на 0% — и пользователи вернутся к старой версии.
- Тестирование новых фич на реальных пользователях без затрат на staging: можно включить canary только для определённой группы (по cookie или гео).
Например, в одном проекте мы обнаружили, что новая версия API вызывает N+1 запрос к базе — на 5% трафика latency выросла на 200%. Canary автоматически откатил версию, и мы исправили проблему без массового сбоя.
Ручное изменение веса в Nginx — это 5 минут даунтайма для редактирования конфига и перезагрузки. Автоматический rollout с проверкой метрик сокращает это до нуля. Мы реализуем пайплайн, который сам решает: увеличить вес или откатить. В Kubernetes с NGINX Ingress откат в 10 раз быстрее — достаточно удалить canary-ingress.
Реализация: от Nginx до Kubernetes и AWS
Трафик распределяется между стабильной и canary-версией: 95% запросов идёт на старую версию, 5% — на новую. Load Balancer или прокси определяет, какой upstream использовать.
Nginx split_clients
# /etc/nginx/nginx.conf
split_clients "${remote_addr}${http_user_agent}" $upstream_pool {
5% canary; # 5% → новая версия
* stable; # 95% → старая версия
}
upstream stable {
server 10.0.0.10:8080;
}
upstream canary {
server 10.0.0.11:8080; # новая версия
}
server {
location / {
proxy_pass http://$upstream_pool;
}
}
Чтобы изменить процент — редактируем конфиг и перезагружаем Nginx: nginx -s reload.
Canary через Cookie (sticky routing)
# Пользователь всегда попадает в ту же версию
map $cookie_canary $upstream_canary {
"1" canary;
default stable;
}
# Или принудительно включить для тестировщиков
map $http_x_canary_override $upstream_override {
"true" canary;
default $upstream_canary;
}
Как настроить Canary-деплой в Kubernetes?
# stable-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-stable
spec:
replicas: 10
selector:
matchLabels:
app: myapp
version: stable
template:
metadata:
labels:
app: myapp
version: stable
spec:
containers:
- name: myapp
image: registry/myapp:v1.0.0
---
# canary-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-canary
spec:
replicas: 2
selector:
matchLabels:
app: myapp
version: canary
template:
metadata:
labels:
app: myapp
version: canary
spec:
containers:
- name: myapp
image: registry/myapp:v1.1.0
---
# canary-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "5" # 5% трафика
spec:
rules:
- host: example.com
http:
paths:
- path: /
backend:
service:
name: myapp-canary-svc
port: { number: 80 }
Управление весом через kubectl: kubectl annotate ingress myapp-canary nginx.ingress.kubernetes.io/canary-weight=25 --overwrite. При полном переходе обновляем stable deployment и удаляем canary: kubectl delete ingress myapp-canary и kubectl delete deployment myapp-canary.
AWS: Weighted Target Groups
import boto3
elbv2 = boto3.client('elbv2')
def set_canary_weight(listener_arn: str, stable_tg: str, canary_tg: str, canary_weight: int):
"""stable_weight + canary_weight должны давать 100"""
stable_weight = 100 - canary_weight
elbv2.modify_listener(
ListenerArn=listener_arn,
DefaultActions=[{
'Type': 'forward',
'ForwardConfig': {
'TargetGroups': [
{'TargetGroupArn': stable_tg, 'Weight': stable_weight},
{'TargetGroupArn': canary_tg, 'Weight': canary_weight},
],
'TargetGroupStickinessConfig': {
'Enabled': True,
'DurationSeconds': 3600, # stickiness 1 час
}
}
}]
)
Автоматический Canary с анализом метрик
# canary-rollout.py
import time
import boto3
import requests
PROMETHEUS_URL = "http://prometheus:9090"
def get_error_rate(version: str, duration: str = "5m") -> float:
query = f'rate(http_requests_total{{version="{version}",status=~"5.."}}[{duration}]) / rate(http_requests_total{{version="{version}"}}[{duration}])'
r = requests.get(f"{PROMETHEUS_URL}/api/v1/query", params={"query": query})
result = r.json()["data"]["result"]
return float(result[0]["value"][1]) if result else 0.0
def progressive_rollout():
steps = [5, 10, 25, 50, 75, 100]
canary_weight = 0
for target_weight in steps:
print(f"Setting canary weight to {target_weight}%")
set_canary_weight(LISTENER_ARN, STABLE_TG, CANARY_TG, target_weight)
# Ждать и проверять метрики
time.sleep(300) # 5 минут на каждом шаге
error_rate = get_error_rate("canary")
print(f"Canary error rate: {error_rate:.2%}")
if error_rate > 0.01: # >1% ошибок
print(f"Error rate too high ({error_rate:.2%}), rolling back!")
set_canary_weight(LISTENER_ARN, STABLE_TG, CANARY_TG, 0)
return False
print("Canary rollout complete!")
return True
Как происходит внедрение Canary-деплоя?
- Анализ текущей архитектуры и трафика (1–2 дня).
- Проектирование схемы canary: выбор инструмента (Nginx, K8s Ingress, AWS ALB) (1 день).
- Настройка конфигурации и развёртывание (2–4 дня).
- Интеграция с мониторингом (Prometheus, Grafana, Datadog) (1–2 дня).
- Тестирование и обучение команды (1–2 дня).
- Деплой и поддержка первых дней (1 день).
Итого: от 5 до 10 рабочих дней в зависимости от сложности.
| Метод | Сложность | Время внедрения | Масштабирование | Откат |
|---|---|---|---|---|
| Nginx split_clients | Низкая | 1–2 дня | Ограниченное | Ручной (5 мин) |
| K8s NGINX Ingress | Средняя | 2–4 дня | Автоматическое | Автоматический |
| AWS ALB + Lambda | Высокая | 3–5 дней | Автоматическое | Автоматический |
Чек-лист мониторинга для canary-деплоя
- Error rate на новой версии < 1%
- Latency p95 не увеличился более чем на 10%
- Conversion rate не снизился (если применимо)
- CPU/Memory в норме
- Все внешние API интеграции работают
Что входит в работу
| Что входит | Описание |
|---|---|
| Конфигурация canary (Nginx/K8s/AWS) | Готовая схема с документацией |
| Мониторинг и алерты | Prometheus + Grafana дашборды |
| CI/CD интеграция | GitHub Actions, GitLab CI, или Jenkins |
| Обучение команды (1 session) | Как управлять canary вручную |
| Техническая поддержка 2 недели | Помощь при запуске |
Более 7 лет опыта, 50+ проектов — наша команда сертифицирована и готова взяться за ваш проект. Свяжитесь с нами для консультации — оценим ваш проект за 1 день. Закажите настройку Canary-деплоя под ключ и получите zero-downtime релизы.
Сроки
- Nginx canary на VPS: 1–2 дня
- Kubernetes NGINX Ingress canary: 2–3 дня
- Автоматический rollout с метриками: 3–5 дней







