Стратегии обновления и откат

Стратегия обновления определяет, как Deployment заменяет старые поды новыми — плавно или с простоем — и насколько безопасно вы сможете откатиться.

Стратегия обновления — правило, по которому Deployment выкатывает новую версию: RollingUpdate заменяет поды постепенно без простоя, Recreate сначала гасит все старые, потом поднимает новые.

Базовый Deployment вы уже умеете создавать и обновлять. Этот урок — про контроль над обновлением: как идёт замена подов, сколько лишних поднимается и сколько можно временно потерять, как откатиться на прошлую версию одной командой и как концептуально устроены blue-green и canary. Это та часть, которая отделяет «выкатил и надеюсь» от предсказуемого релиза без простоя.

RollingUpdate против Recreate

У Deployment две встроенные стратегии. RollingUpdate (по умолчанию) заменяет поды порциями: поднимает несколько новых, дожидается их готовности, гасит столько же старых — и так, пока вся выкатка не завершится. В каждый момент часть подов обслуживает трафик, поэтому простоя нет.

Recreate действует резко: сначала удаляет все старые поды, и лишь затем создаёт новые. Между этими шагами приложение недоступно. Это допустимо там, где две версии не могут работать одновременно — например, при несовместимой миграции схемы БД или при эксклюзивном захвате ресурса.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 4
  strategy:
    type: Recreate        # все старые поды гасятся до создания новых
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: web:2.0

maxSurge и maxUnavailable

Поведение RollingUpdate тонко настраивается двумя параметрами. Они задаются числом подов или процентом от replicas:

ПараметрСмыслПо умолчанию
maxSurgeСколько подов сверх желаемого числа можно поднять во время выкатки25%
maxUnavailableСколько подов из желаемого числа можно временно держать недоступными25%
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1            # не более чем на 1 под больше нормы
      maxUnavailable: 0      # ни одного пода не теряем во время выкатки

Комбинация maxUnavailable: 0 и maxSurge: 1 даёт самый бережный режим: Kubernetes сначала поднимает один лишний новый под, дожидается его готовности и только потом гасит один старый — мощность сервиса не проседает ни на секунду. Обратная крайность, maxUnavailable: 1, maxSurge: 0, обновляет «впритык», не превышая лимит подов, но временно теряя часть мощности. Выбор — это компромисс между запасом ресурсов и гарантированной ёмкостью во время релиза.

# Запустить обновление, сменив образ
kubectl set image deployment/web web=web:2.0

# Следить за ходом выкатки в реальном времени
kubectl rollout status deployment/web

Откат: rollout undo

Deployment хранит историю ревизий, поэтому неудачный релиз откатывается одной командой — это главная страховка при выкатке.

# Посмотреть историю ревизий
kubectl rollout history deployment/web

# Откатиться на предыдущую ревизию
kubectl rollout undo deployment/web

# Откатиться на конкретную ревизию
kubectl rollout undo deployment/web --to-revision=3

# Аварийно остановить и возобновить выкатку
kubectl rollout pause deployment/web
kubectl rollout resume deployment/web

Откат — это, по сути, та же выкатка, только к прошлому шаблону пода: Kubernetes возвращает предыдущий ReplicaSet и плавно переводит трафик на него по той же стратегии RollingUpdate. Глубину истории задаёт поле revisionHistoryLimit (по умолчанию 10 хранимых ReplicaSet).

Blue-green и canary концептуально

RollingUpdate и Recreate — встроенные стратегии. Blue-green и canary — это паттерны поверх Kubernetes: их собирают из нескольких Deployment и управления трафиком (через Service, Ingress или service mesh), а в проде обычно автоматизируют инструментами вроде Argo Rollouts или Flagger.

Blue-green

Поднимаются две полные среды: blue (текущая версия) и green (новая). Трафик идёт на blue. Когда green развёрнута и проверена, переключают Service с blue на green одним движением — мгновенный «перевод стрелки». Если что-то не так, так же мгновенно возвращаются на blue. Плюс — нулевой простой и быстрый откат; минус — нужно вдвое больше ресурсов, ведь обе среды работают одновременно.

Canary

Новая версия выкатывается постепенно: сначала на неё направляют, скажем, 5% трафика, наблюдают метрики (ошибки, задержки), затем поднимают долю до 25%, 50% и, если всё хорошо, до 100%. Так проблему ловят на малой части пользователей. Простейший canary имитируется и «голым» Kubernetes: рядом с основным Deployment поднимают второй, с новым образом и малым числом реплик, под тем же Service — и доля трафика на новую версию определяется соотношением подов. Точное процентное управление дают service mesh и специализированные контроллеры.

Как это работает под капотом

За кулисами Deployment управляет несколькими ReplicaSet. При обновлении создаётся новый ReplicaSet с новым шаблоном пода; контроллер постепенно увеличивает в нём число реплик и одновременно уменьшает их в старом, соблюдая maxSurge и maxUnavailable. Старые ReplicaSet не удаляются, а остаются с нулём реплик — именно они и образуют историю ревизий. Поэтому rollout undo работает мгновенно: контроллеру достаточно снова «надуть» прежний ReplicaSet и сдуть текущий.

Готовность новых подов определяют пробы (readinessProbe): пока под не прошёл readiness, он не считается доступным и выкатка не двигается дальше. Поэтому без корректных проб RollingUpdate может «считать» сырые поды рабочими и отправлять на них трафик раньше времени — пробы напрямую влияют на безопасность обновления.

Частые ошибки

  • maxUnavailable и maxSurge одновременно в нуле. Так выкатка не сдвинется: нельзя ни поднять лишний под, ни погасить существующий. Хотя бы один параметр должен допускать движение.
  • RollingUpdate при несовместимых версиях. Если новая и старая версии не могут сосуществовать (несовместимая схема БД, общий эксклюзивный ресурс), параллельная работа во время выкатки сломает приложение — здесь нужен Recreate или blue-green.
  • Нет readiness-проб. Без них Kubernetes считает поды готовыми сразу после старта и переводит трафик на ещё не прогретое приложение — пользователи ловят ошибки прямо во время релиза.
  • Расчёт на бесконечную историю откатов. Глубина ограничена revisionHistoryLimit; слишком старую ревизию откатить уже не выйдет.
  • Путаница maxSurge и maxUnavailable. maxSurge — про поды сверх нормы, maxUnavailable — про допустимую нехватку. Перепутав их, легко получить не тот профиль доступности.

Итоги

  • RollingUpdate заменяет поды постепенно без простоя; Recreate гасит все старые до создания новых, с коротким простоем.
  • maxSurge — сколько подов можно поднять сверх нормы, maxUnavailable — сколько можно временно потерять; вместе они задают профиль безопасности выкатки.
  • kubectl rollout undo мгновенно откатывает релиз, возвращая предыдущий ReplicaSet; rollout status/history/pause/resume управляют выкаткой.
  • Blue-green переключает трафик между двумя полными средами; canary постепенно наращивает долю трафика на новую версию.
  • Корректные readiness-пробы критичны: от них зависит, безопасно ли идёт обновление.
Проверьте себя
1. В чём разница между стратегиями RollingUpdate и Recreate?
ARollingUpdate гасит все поды сразу, Recreate — постепенно
BRollingUpdate заменяет поды постепенно без простоя, Recreate сначала гасит все старые, потом создаёт новые
CОни идентичны, отличаются только названием
DRecreate работает без простоя, а RollingUpdate всегда вызывает простой
2. Что задаёт параметр maxUnavailable в стратегии RollingUpdate?
AСколько подов можно поднять сверх желаемого числа во время выкатки
BСколько подов из желаемого числа можно временно держать недоступными во время выкатки
CСколько всего ревизий хранить в истории
DЧерез сколько секунд считать под готовым
3. Какая команда откатывает Deployment на предыдущую версию?
Akubectl rollout status deployment/web
Bkubectl rollout undo deployment/web
Ckubectl delete deployment/web
Dkubectl scale deployment/web --replicas=0
4. Чем canary-выкатка отличается от blue-green?
ACanary мгновенно переключает весь трафик между двумя средами
BCanary постепенно направляет на новую версию растущую долю трафика, наблюдая за метриками
CCanary требует ровно вдвое больше ресурсов, чем основная среда
DCanary доступен только через стратегию Recreate