Викотили нову версію, а через півгодини — лавина помилок і падіння конверсії? 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 днів







