Canary deployment: как проверять новую версию на части трафика

Canary deployment: как проверять новую версию на части трафика

После тестов новая версия приложения всё равно впервые сталкивается с реальным production-трафиком, реальными данными и рабочими зависимостями. Canary deployment уменьшает масштаб этого первого контакта: старая стабильная версия продолжает обслуживать основную нагрузку, а release candidate получает только ограниченную часть трафика.

Если canary ведёт себя ожидаемо, долю постепенно увеличивают. Если появляются существенные проблемы, rollout останавливают или возвращаются к известной рабочей версии. Поэтому canary — это не просто «выкатить на несколько серверов». Это управляемая последовательность состояний: небольшое воздействие → наблюдение → решение → следующий этап или остановка.

Что именно называется canary deployment

Google SRE описывает canary как небольшой сегмент production, на котором запускается release candidate и который получает часть реального трафика. Поведение новой версии сравнивается с остальной частью системы, где продолжает работать текущая stable-версия.

Упрощённая модель выглядит так:

Production traffic
        ↓
   traffic routing
      ↙       ↘
 stable      canary
   v1          v2
  95%          5%

Проценты здесь только пример. Универсального стартового значения для всех сервисов нет. Размер canary зависит от характера нагрузки, допустимого риска, скорости обнаружения проблем и того, сколько данных требуется для содержательного сравнения.

Главная особенность подхода — старая и новая версии некоторое время существуют одновременно. Это позволяет не заменять весь production одним действием.

Canary уменьшает область воздействия, но не делает релиз безопасным автоматически

Если дефект находится в новой версии, ограниченная доля трафика уменьшает число запросов, которые сразу сталкиваются с этим дефектом. В этом и состоит одна из основных причин использовать canary.

Но небольшой rollout не исправляет сам release candidate. Если система не умеет:

  • отделять трафик canary от stable;
  • видеть состояние каждой версии отдельно;
  • останавливать продвижение;
  • возвращаться к рабочему состоянию;
  • понимать, какие критерии считаются допустимыми;

то ограниченная группа сама по себе мало помогает.

Google SRE выделяет для canary-процесса три базовые способности: развернуть изменение на подмножестве production, оценить его и встроить результат оценки в release process.

Canary deployment и rolling update — не одно и то же

Обе стратегии могут некоторое время держать старые и новые экземпляры одновременно, поэтому их легко перепутать.

Обычный rolling update постепенно заменяет старые экземпляры новыми, сохраняя доступность приложения. Kubernetes Deployment, например, создаёт новые Pods и поэтапно уменьшает число старых в рамках параметров maxSurge и maxUnavailable.

Canary добавляет другую задачу: новая версия намеренно задерживается на ограниченной доле production, чтобы её можно было оценить до полного продвижения.

Свойство Rolling update Canary deployment
Основная задача Постепенно заменить старую версию новой Сначала проверить новую версию на ограниченной доле production
Паузы для анализа Не являются обязательной сущностью стратегии Обычно являются важной частью rollout
Сравнение stable и candidate Может не быть отдельной целью Является основой принятия решения
Следующий шаг Продолжение замены экземпляров Расширение, пауза или abort по результатам оценки

То есть canary стоит рассматривать не как более медленный rolling update, а как rollout с отдельной фазой проверки.

Разница между canary deployment и rolling update

Доля экземпляров и доля трафика — тоже не всегда одно и то же

Допустим, приложение состоит из десяти одинаковых экземпляров. Один экземпляр новой версии выглядит как 10% canary.

Но из этого ещё не следует, что он гарантированно получит ровно 10% запросов.

При простом балансировании трафик может распределяться приблизительно по числу экземпляров. На реальную долю влияют длительность соединений, особенности балансировщика, sticky sessions, неравномерность запросов и другие свойства системы.

Argo Rollouts прямо разделяет два режима. Без отдельного traffic manager контроллер подбирает количество stable- и canary-replicas и лишь приближает требуемый вес. С traffic routing можно управлять процентом трафика гораздо точнее.

Поэтому перед rollout нужно определить, чем именно управляет система:

  • числом экземпляров;
  • весом backend;
  • правилами proxy или ingress;
  • маршрутизацией service mesh;
  • другим механизмом распределения запросов.

«10% canary» должно иметь технически определённый смысл, а не быть только цифрой в плане релиза.

Первый этап обычно делают небольшим не ради символического процента

В начале rollout команда меньше всего знает о поведении release candidate в production. Поэтому логично ограничить потенциальное воздействие.

Но слишком маленькая группа тоже создаёт проблему. Если canary получил несколько запросов, отсутствие ошибок ещё ничего не говорит о сценариях, которые он не успел обработать.

Google SRE предлагает учитывать сразу несколько параметров:

  • размер canary-группы;
  • длительность этапа;
  • объём полученного трафика;
  • репрезентативность запросов;
  • время суток и характер нагрузки;
  • метрики, которым требуется разное время для проявления.

Поэтому вопрос «какой процент выбрать?» без контекста неполон. Для высоконагруженного однородного API небольшой процент способен быстро дать большой объём запросов. Для редкой операции даже заметная доля трафика может долго не создавать достаточного числа наблюдений.

Длительность canary зависит от того, какую проблему нужно успеть увидеть

Слишком короткий этап может пропустить дефект, который проявляется не сразу.

Например:

  • утечка памяти накапливается со временем;
  • очередь растёт постепенно;
  • ошибка проявляется только при пиковом трафике;
  • редкий сценарий встречается несколько раз в сутки;
  • фоновая задача запускается по расписанию.

С другой стороны, слишком длинная canary-фаза замедляет весь release process и дольше оставляет production в смешанном состоянии.

Google SRE связывает длительность canary не только с технической репрезентативностью, но и со скоростью выпуска. Команда, выпускающая изменения много раз в день, не может оценивать каждый canary неделю. Поэтому длительность выбирается как компромисс между скоростью получения достаточных данных и стоимостью задержки релиза.

Лучше сравнивать canary со stable одновременно, а не только «до» и «после»

Если полностью заменить старую версию, а затем сравнить сегодняшние метрики со вчерашними, в сравнение автоматически попадает время.

За это время могли измениться:

  • число пользователей;
  • структура запросов;
  • фоновая нагрузка;
  • состояние внешних сервисов;
  • профиль данных.

Google SRE отдельно предупреждает о рисках before/after evaluation. Одновременные stable и canary дают более содержательную основу: обе версии работают в близком временном контексте.

Это всё равно не создаёт идеальной лабораторной изоляции. Stable и canary могут использовать одну базу данных, сеть и внешние сервисы. Но такое сравнение обычно позволяет лучше отделить изменение версии от обычной динамики production.

Метрики нужно уметь разделять по версиям

Предположим, canary обслуживает небольшую часть запросов и почти все ошибки возникают именно там. На общем графике сервиса они могут раствориться среди успешного stable-трафика.

Поэтому для анализа важно видеть данные отдельно:

stable → собственные наблюдения
canary → собственные наблюдения.

Google SRE показывает именно такую проблему: общий показатель всего сервиса способен скрыть дефект малой canary-популяции, тогда как разбиение по версии делает различие заметным.

Какие именно логи, метрики и трассировки нужны для такого разделения — отдельный инженерный вопрос. Его разберём в материале о наблюдаемости системы до и во время эксперимента.

Продвижение canary лучше описывать как последовательность состояний

Этапы принятия решения при canary rollout

Вместо правила «если всё нормально, постепенно увеличивать процент» полезно заранее определить конкретные этапы.

Например:

stable 100%
    ↓
canary: малая доля
    ↓
pause + evaluation
   ↙          ↘
abort       continue
              ↓
       canary: больше
              ↓
       pause + evaluation
           ↙      ↘
        abort    promote
                   ↓
              stable 100%

Argo Rollouts реализует похожую модель декларативно: шаг setWeight задаёт долю canary, а pause останавливает продвижение на заданное время или до ручного продолжения. AnalysisRun может дополнительно влиять на решение продолжить, остановить или признать результат неопределённым.

Ценность такой схемы не в конкретном инструменте. Состояния rollout становятся заранее известными и их легче зафиксировать в журнале изменений.

Критерии продолжения нужно определить до проблемного релиза

Фраза «посмотрим на графики и решим» оставляет слишком много пространства для субъективного решения уже после получения результата.

До запуска полезно определить хотя бы:

Вопрос Что нужно решить заранее
Что считаем критической проблемой? Условия немедленного abort или rollback
Что считаем допустимым? Границы поведения для продолжения rollout
Сколько длится этап? Минимальное время или объём наблюдений
Что делаем при неоднозначном результате? Пауза, дополнительное наблюдение или ручная проверка
Кто принимает решение? Автоматическая система, оператор или оба уровня

Google SRE рекомендует выбирать небольшое число показателей, которые действительно отражают пользовательские проблемы, а не пытаться включить в canary evaluation все доступные метрики.

Главная задача критериев — сделать переход между стадиями воспроизводимым. Один и тот же результат не должен сегодня считаться причиной продолжить rollout, а завтра — поводом остановить его только потому, что изменилось настроение команды.

Abort, rollback и остановка трафика — не всегда одно действие

Если canary показывает проблему, первая задача — не дать новой версии расширить область воздействия.

Но дальнейшее действие зависит от архитектуры.

Можно:

  • остановить продвижение на текущей стадии;
  • перенаправить трафик обратно на stable;
  • уменьшить число canary-экземпляров;
  • откатить Deployment на предыдущую revision;
  • развернуть исправленную версию.

При этом инфраструктурный rollback не обязательно возвращает вообще всё состояние системы.

Например, Kubernetes Deployment при rollback возвращает предыдущую версию Pod template. Отдельно изменённая схема базы, внешняя конфигурация или уже записанные данные таким rollback автоматически не отменяются.

Поэтому возможность возврата нужно проектировать для конкретного изменения, а не считать, что команда rollback универсально обращает релиз назад.

Canary и feature flag управляют разными слоями

В предыдущем материале мы разбирали feature flags. Эти механизмы можно комбинировать, но их роли различаются.

Feature flag Canary deployment
Выбирает поведение внутри развёрнутого приложения Разделяет production между версиями приложения
Один build может иметь несколько вариантов поведения Stable и release candidate существуют одновременно
Часто работает через evaluation context и targeting Часто работает через экземпляры и traffic routing
Переключение флага может не требовать redeploy Canary появляется как отдельная развёрнутая версия

Команда может сначала развернуть v2 как canary, а внутри v2 оставить отдельную функцию выключенной feature flag. В таком случае появляется два независимых состояния, которые нужно записывать отдельно.

Несколько canary одновременно усложняют картину

Технически параллельные canary возможны. Но если они затрагивают общие зависимости или один и тот же поток запросов, становится труднее понять состояние системы.

Google SRE отдельно предупреждает, что одновременные canary увеличивают когнитивную нагрузку на оператора и создают риск загрязнения наблюдений при пересечении воздействий.

Это особенно важно во время инцидента. Вместо простой картины:

stable v1 + canary v2

команда получает несколько release candidate, изменения конфигурации и параллельные rollout разных компонентов.

Если последовательный выпуск практически возможен, он делает дальнейшую диагностику проще.

Canary не гарантирует полной изоляции от stable

Две версии могут одновременно использовать:

  • одну базу данных;
  • общий кэш;
  • очередь;
  • сетевую инфраструктуру;
  • одинаковые внешние API;
  • одни и те же пользовательские данные.

Из-за этого дефект canary иногда способен повлиять и на stable. Например, новая версия создаёт чрезмерную нагрузку на общую базу или изменяет данные, которые затем читает старая версия.

Поэтому маленький процент трафика ограничивает прямое воздействие только в пределах архитектуры. Он не гарантирует, что все побочные эффекты тоже уменьшатся пропорционально.

Эту границу полезно учитывать ещё до выбора canary как стратегии релиза.

Минимальная схема canary deployment

Если убрать детали конкретной платформы, остаётся достаточно понятная процедура.

  1. Определить stable и release candidate. Должно быть понятно, какие две версии сравниваются.
  2. Выбрать механизм распределения. Реплики, load balancer, ingress, service mesh или другой traffic router.
  3. Назначить первую canary-стадию. Размер должен ограничивать риск и при этом давать полезные наблюдения.
  4. Определить длительность. Canary должен успеть получить репрезентативную нагрузку.
  5. Разделить данные stable и canary. Общий график сервиса может скрыть проблему новой версии.
  6. Задать критерии решения. Continue, pause или abort должны опираться на заранее понятные условия.
  7. Расширять постепенно. Чем меньше уверенность, тем меньше начальная область воздействия.
  8. Заранее проверить возврат. Что именно будет означать rollback для кода, конфигурации и данных.
  9. Зафиксировать историю rollout. Доля трафика, время стадий, решения и сопутствующие изменения должны остаться в журнале.

Canary deployment полезен не потому, что новая версия получает маленький процент. Его ценность появляется, когда этот процент является частью управляемого цикла: ограничить воздействие, получить различимые наблюдения и принять следующее решение до полного rollout.

Источники

Технические источники проверены 19 августа 2026 года. Использованы официальные материалы Google SRE, Kubernetes и Argo Rollouts.