Представь: ты полночи деплоишь обновление, говоришь команде «готово», идёшь спать — а утром узнаёшь, что корзина в магазине сломалась и полтысячи заказов потеряно. Знакомо? Именно от этого сценария и спасает canary deployment.
Что это вообще такое
Canary deployment — это когда ты выкатываешь новую версию не сразу всем, а сначала маленькой доле пользователей. Скажем, 1–5%. Смотришь, как оно себя ведёт, следишь за метриками. Если всё хорошо — постепенно расширяешь аудиторию. Если что-то пошло не так — откатываешь, пока большинство пользователей ничего не заметило.
Название — отсылка к шахтёрской практике XIX века. Горняки брали с собой канарейку: если птица переставала петь, значит, в шахте скопился угарный газ и надо валить. Канарейка жертвовала собой ради остальных. Примерно так же работает и маленький процент пользователей, которые первыми получают новый код.
Чем canary отличается от blue-green и rolling
Часто эти три подхода путают, поэтому давай расставим по местам.
Blue-green deployment — у тебя две идентичные среды: синяя (текущая) и зелёная (новая). Ты переключаешь трафик целиком с одной на другую. Быстро, чисто, но дорого: нужно держать две полных копии инфраструктуры. И если что-то сломалось — 100% пользователей уже на новой версии до того, как ты это заметил.
Rolling deployment — постепенно заменяешь старые инстансы новыми. Kubernetes делает это по умолчанию. Но здесь нет контроля над тем, кто именно получает новую версию — просто часть запросов идёт на новые поды, часть на старые.
Canary — ты явно управляешь распределением трафика. Говоришь: «1% запросов — на новую версию, 99% — на старую». Можешь таргетировать конкретных пользователей: бета-тестеров, пользователей из определённого региона, тех, у кого флаг early_access = true. Это самый гибкий и безопасный вариант.
Как это устроено технически
Есть несколько уровней, на которых можно реализовать canary.
На уровне балансировщика
Samый простой способ — настроить Nginx или HAProxy так, чтобы часть запросов шла на новые инстансы. В Nginx это выглядит примерно так:
upstream backend {
server old-app:8080 weight=99;
server new-app:8080 weight=1;
}
Это даёт тебе грубое управление: 1% трафика на новую версию. Но никакой гранулярности — один и тот же пользователь может попасть то на старую версию, то на новую в разных запросах. Для stateless-сервисов это нормально, для stateful — может быть проблемой.
На уровне Kubernetes
Если работаешь с k8s, можно держать два Deployment: app-stable и app-canary. Управляешь соотношением через количество реплик:
# stable: 9 реплик
# canary: 1 реплика
# итого 10% на canary
Но это грубо. Для точного управления трафиком лучше использовать service mesh — Istio или Linkerd. Istio позволяет прописать правила типа:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
spec:
http:
- match:
- headers:
x-canary-user:
exact: "true"
route:
- destination:
host: app-canary
- route:
- destination:
host: app-stable
weight: 95
- destination:
host: app-canary
weight: 5
Теперь ты можешь отправлять на canary конкретных пользователей (по заголовку) плюс 5% случайных.
Feature flags как canary
Ещё один подход — выкатить новый код всем, но скрыть его за флагом. Функциональность включается не для всех, а для выбранной группы. Это популярно в больших командах: LaunchDarkly, Unleash, самописные решения на Redis.
Плюс — код един, нет двух параллельных версий на инфраструктуре. Минус — технический долг растёт, если флаги не убирать вовремя.
Метрики: что смотреть во время canary
Canary без мониторинга — это как прыгать с парашютом вслепую. Ты должен заранее определить, что именно будешь мерить и какие пороги считаются нормой.
Ошибки (error rate). Базовый показатель. Если на stable 0.1% ошибок, а на canary вдруг 2% — стоп, откат.
Latency (p50, p95, p99). Новая версия может работать корректно, но медленнее. Пользователи это почувствуют. Следи не только за средним временем ответа, но и за хвостами распределения.
Бизнес-метрики. Это самое важное и самое сложное. Конверсия, добавление в корзину, завершённые оформления заказов. Техническая исправность не равна бизнесовой. Бывает, код не кидает ошибки, но пользователи почему-то перестают покупать.
Saturation. Потребление CPU, памяти, дискового I/O. Иногда новая версия работает нормально под малой нагрузкой, но течёт по памяти — и ты увидишь это только при постепенном росте.
Всё это должно быть в дашборде рядом с кнопкой «расширить canary» и «откатить». Grafana + Prometheus — стандартный выбор. DataDog, New Relic — если бюджет позволяет.
Автоматизация: когда робот решает за тебя
Ручной canary — это когда ты сам смотришь на графики и принимаешь решение. Это нормально для небольших команд.
Автоматизированный canary — система сама сравнивает метрики canary и stable, и либо продвигает деплой дальше, либо откатывает. Это называется progressive delivery.
Flagger — опенсорсный инструмент для k8s, который делает именно это. Ты описываешь политику:
apiVersion: flagger.app/v1beta1
kind: Canary
spec:
analysis:
interval: 1m
threshold: 5 # максимум 5 неудачных проверок
maxWeight: 50 # максимум 50% на canary
stepWeight: 10 # шаг 10%
metrics:
- name: request-success-rate
min: 99 # минимум 99% успешных запросов
- name: request-duration
max: 500 # максимум 500ms на p99
Flagger каждую минуту проверяет метрики. Если всё хорошо — добавляет 10% к canary. Если метрики падают ниже порога 5 раз подряд — автоматически откатывает и уведомляет в Slack.
Argo Rollouts — альтернатива от команды Argo, тоже популярна в k8s-экосистеме.
Типичные ошибки
Слишком маленькая выборка. Если на canary идёт 0.1% трафика при 100 запросах в сутки — это 0.1 запроса. Ты ничего не увидишь. Canary нужна статистически значимая нагрузка. Для нагруженных сервисов 1% может быть достаточно; для маленьких — возможно, нужно 10–20%.
Слишком быстрое продвижение. «Десять минут на каждый шаг» — звучит разумно, пока не выяснится, что баг проявляется только через час работы сессии. Интервал наблюдения должен соответствовать паттернам использования.
Нет rollback-плана. Canary хороша именно тем, что откат быстрый. Но «быстрый» значит «заранее проверенный». Ты должен знать точно: как откатить, сколько времени займёт, нужна ли миграция базы.
Несовместимые миграции базы данных. Canary предполагает, что два варианта кода работают одновременно. Если новая версия добавляет поле в БД и делает его обязательным — старая версия начнёт падать. Правило простое: любая миграция базы должна быть обратно совместимой с предыдущей версией кода. Сначала добавляешь поле как nullable, потом деплоишь новый код, потом делаешь поле обязательным.
Игнорирование бизнес-метрик. Технические метрики в порядке, а конверсия упала на 15% — и ты этого не заметил, потому что не смотрел. Договорись с продуктом заранее, что именно мерить.
Когда canary не нужен
Не каждый деплой требует canary. Это инструмент с накладными расходами: нужна инфраструктура, мониторинг, дисциплина команды.
Canary оправдан, когда:
- сервис критичный (платежи, авторизация, заказы)
- аудитория большая, цена ошибки высокая
- изменение нетривиальное — новый алгоритм, рефакторинг ядра
Можно обойтись без canary:
- правишь опечатку в тексте
- меняешь конфиг, который легко откатить
- сервис внутренний, нагрузка маленькая, пользователи терпимы к авариям
Веб-студия REEXY при разработке корпоративных сайтов и интернет-магазинов всегда обсуждает с клиентом стратегию деплоя: для простых визиток достаточно прямого обновления, для нагруженного e-commerce — продуманный staging и поэтапный выкат.
Практический чеклист перед canary
Прежде чем нажать кнопку, пройдись по списку:
- Метрики настроены и разбиты по версиям (stable vs canary)
- Определены пороги: что считается «плохо» для error rate, latency, бизнес-метрик
- Есть алерты с коротким временем реакции (не 1 час, а 5 минут)
- Rollback-процедура задокументирована и проверена
- Миграции БД обратно совместимы
- Команда знает, кто принимает решение о продвижении или откате
- Время деплоя выбрано с умом — не пятница вечер, не пиковый час нагрузки
Инструменты, которые стоит знать
Flagger — автоматизированный canary для k8s, работает с Istio, Linkerd, Nginx, Traefik.
Argo Rollouts — расширяет k8s Deployment canary и blue-green стратегиями, хорошая интеграция с Argo CD.
Spinnaker — тяжёлая платформа continuous delivery от Netflix, canary analysis встроен.
LaunchDarkly / Unleash — feature flags, если хочешь управлять canary на уровне кода, а не инфраструктуры.
Grafana + Prometheus — база для метрик и дашбордов.
Для тех, кто только начинает и хочет простое решение: настрой два Deployment в k8s с разным количеством реплик, сделай дашборд в Grafana и назначь человека, который раз в 15 минут смотрит на графики во время деплоя. Это уже canary — пусть и ручной.
Как это выглядит в реальном деплое
Вот пример последовательности для e-commerce:
- Выкатываем canary на 2% трафика. Ждём 30 минут.
- Error rate в норме (0.08% против 0.07% на stable). Latency не изменилась. Добавления в корзину — в пределах нормального разброса.
- Расширяем до 10%. Ждём час — это покрывает один цикл пика активности.
- Всё хорошо. Расширяем до 50%, смотрим ещё 30 минут.
- Деплоим на 100%, убираем canary-инстанс.
Весь процесс занял около двух часов. Если бы на шаге 2 error rate вырос до 1% — откат занял бы 30 секунд, и 98% пользователей ничего бы не заметили.
При правильно выстроенной инфраструктуре заказать интернет-магазин с профессиональной стратегией деплоя у той же REEXY можно от 10 000 ₽, и вопросы надёжности выкатки обновлений будут частью обсуждения с самого начала.
Canary deployment — это не серебряная пуля. Но это один из немногих инструментов, который позволяет выкатывать изменения с реально управляемым риском. Начни с малого: два Deployment, базовый мониторинг, фиксированный процент. Остальное придёт с практикой.