Canary и Progressive Delivery: как выкатывать изменения без страха¶
Представьте, что вы шеф-повар и придумали новое блюдо. Вы не выносите его сразу в большой зал всем посетителям. Сначала пробуете сами. Потом даёте попробовать коллеге. Потом ставите в меню как специальное предложение на один день. И только если все в восторге — вводите в постоянное меню.
Progressive Delivery — это точно такой же подход к выкатке кода. Вы не включаете новую версию сразу всем пользователям. Вы катите её постепенно, на каждом шаге проверяя, что всё работает, и имея возможность откатиться за секунды.
Почему это важно для SRE?¶
Большинство инцидентов вызвано изменениями (см. главу «Почему большинство инцидентов вызвано изменениями?»). Чем быстрее и шире вы катите изменение, тем больше blast radius. Progressive Delivery — это про то, чтобы сделать blast radius управляемым.
Но есть и второй, не менее важный эффект: Progressive Delivery снижает MTTR до нуля для большинства проблем. Если вы заметили проблему на 1% трафика — MTTR считается в секундах (просто откатили канарейку). Если вы заметили её на 100% — MTTR считается в часах (деплой предыдущей версии, перезапуск всех инстансов, проверка).
Спектр стратегий¶
Progressive Delivery — это зонтичный термин. Под ним прячутся несколько стратегий, которые можно комбинировать:
1. Ramped Deployment (постепенная раскатка)¶
Классика. Новая версия замещает старую порциями: 10% → 25% → 50% → 100%.
Старая версия: ████████████████████████████████████████
Новая версия: ░░░░░░░░░░
Шаг 1 (10%): ██████████████████████████████████████████░░░░░░░░░░
...
Шаг N (100%): ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
Когда использовать: обычные релизы, где нет жёстких требований к мгновенному переключению. Просто, надёжно, работает.
Риск: на каждом шаге есть небольшой период, когда обе версии работают одновременно. Нужно убедиться, что они совместимы (нет проблем с обратной совместимостью API, миграциями БД и т.д.).
2. Canary Deployment¶
Вы поднимаете отдельный пул инстансов с новой версией и направляете на него малый процент трафика.
Канареечный пул (2%): ░░░░
Старый пул (98%): ████████████████████████████████████████
Canary-деплой был описан в главе «Постепенное снижение риска». Ключевое отличие от ramped — вы держите канареечный пул изолированно и можете мгновенно снять с него трафик, оставив старые инстансы нетронутыми.
Когда использовать: критичные сервисы, где откат рампом слишком долог. Сервисы с реальным пользовательским трафиком, где важно проверить поведение под нагрузкой.
Что измерять на канарейке: - Латентность (p50, p95, p99) — не просела ли? - Коды ответов — не вырос ли процент 5xx? - Потребление ресурсов (CPU, RAM) — не утекло ли что-то? - Бизнес-метрики (конверсия, заказы) — не упала ли? — это уже A/B-тест, не всегда обязателен
3. Blue-Green Deployment¶
Два идентичных окружения (Blue и Green). В один направлен весь трафик, во втором — новая версия. Переключение мгновенное:
- Blue — текущий продакшен
- Green — подготовленная новая версия
- Переключили балансировщик — и всё.
Когда использовать: сервисы, где важна мгновенная среда с полным набором данных (нельзя просто поднять 2% подов, нужна вся инфраструктура). Ситуации, когда нужно быстро переключаться между версиями туда-сюда.
Цена: нужно вдвое больше ресурсов. В Kubernetes это означает два полных набора подов, что дорого. Blue-Green часто используют для баз данных или stateful-сервисов, где ramped-деплой невозможен.
4. A/B-тестирование (эксперименты)¶
Это уже не про техническую надёжность, а про бизнес-метрики. Разным группам пользователей показывают разные версии функциональности и замеряют, какая лучше.
Группа A (50%): ████████████████████████████████████████ старая версия
Группа B (50%): ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ новая версия
Отличие от canary: canary проверяет «не сломалось ли». A/B-тест проверяет «стало ли лучше». Для canary достаточно технических метрик. Для A/B нужна бизнес-аналитика, статзначимость и разделение пользователей по ID.
5. Feature Flags (флаги функций)¶
Это отдельный инструмент, который позволяет включать и выключать функциональность без деплоя. Feature flags можно комбинировать с любой из стратегий выше. Подробно разобрано в главе «Feature Flags: рубильники безопасности для продакшена».
Сводная таблица¶
| Стратегия | Blast radius | Скорость отката | Сложность | Ресурсы |
|---|---|---|---|---|
| Ramped | Средний | Средняя | Низкая | N |
| Canary | Низкий | Высокая | Средняя | N + canary |
| Blue-Green | Полный | Мгновенная | Средняя | 2N |
| A/B-тест | Зависит | Средняя | Высокая | N + аналитика |
| Feature Flags | Минимальный | Секунды | Средняя | N + сервис флагов |
Какую стратегию выбрать?¶
Зависит от контекста:
- Если у вас 10 микросервисов и одна команда — ramped + feature flags решают 90% задач.
- Если у вас high-load, критичный сервис — canary как обязательный стандарт, поверх — feature flags.
- Если в сервисе состояние (stateful, БД) — blue-green или сложные паттерны миграций.
- Если бизнес хочет данные — A/B-тесты поверх любой технической стратегии.
Progressive Delivery и SLO¶
Progressive Delivery становится ещё мощнее в связке с SLO. Идея: автоматически приостанавливать раскатку, если SLO начал нарушаться.
# Псевдокод: пайплайн progressive delivery с проверкой SLO
steps:
- canary: 2%
duration: 5m
check: SLO_green? # Все SLI в норме?
- ramp: 25%
duration: 10m
check: SLO_green?
- ramp: 50%
duration: 10m
check: SLO_green?
- ramp: 100%
duration: 0
Если на любом шаге SLO просел — пайплайн останавливается, автоматический откат, нотификация в чат.
Автоматический откат по SLO¶
Это самый зрелый уровень. Система сама решает, катить дальше или нет:
- Выкатили канарейку на 2%.
- Система мониторит SLI (латентность, ошибки).
- Если SLI выходят за SLO — пайплайн сам отзывает canary и шлёт уведомление.
- Если всё зелёное — пайплайн раскатывает дальше.
Человек участвует только в анализе причины остановки. Принятие решения «катить или нет» делегировано автоматике. Подробнее — в главе «SLO как код».
Технические сложности¶
Progressive Delivery прекрасен в теории, но на практике есть подводные камни:
- Совместимость данных. Если новая версия меняет схему БД, то ramped-деплой может сломать старые инстансы, которые пишут по-старому, а читают по-новому. Решение: миграции БД вперёд-назад (forward/backward compatible), разделение деплоя кода и миграции схемы.
- Сессии пользователей. Если пользователь попал на новую версию, а при следующем запросе — на старую, он может увидеть глюки. Решение: sticky sessions (привязка к инстансу) или stateless-архитектура.
- Метрики и мониторинг. Нужно уметь разделять метрики по версиям. Без этого вы не поймёте, зеленая канарейка или нет. В Prometheus это решается лейблами
versionиdeployment=canary. Подробнее — в главе «Метрики и проклятие cardinality». - Кэши и CDN. Если вы катите новую версию фронтенда через CDN, старая версия может кешироваться у пользователей на дни. Решение: versioning в URL, короткий TTL для критичных ресурсов.
Итог¶
Progressive Delivery — это не про «как быстро выкатить фичу». Это про «как выкатить фичу так, чтобы в случае проблем никто не пострадал». Это превращает релиз из события (стресс, ночные деплои, молитвы) в процесс (рутинный, автоматизированный, безопасный).
SRE-подход: каждая стратегия хороша в своём контексте. Начинайте с ramped + feature flags. Для критичных сервисов добавляйте canary с автоматической проверкой SLO. И никогда не выкатывайте новую версию сразу на 100% трафика — даже если вы уверены на 200%.