Обновления и откаты на практике

Применим rolling update и откат к нашему backend — без простоя и с подстраховкой.

Обновление в Kubernetes — это смена образа в манифесте Deployment и повторный apply; кластер сам выполняет плавную замену подов.

У нас крутится backend версии 1.0 в двух репликах. Вышла версия 1.1. Посмотрим полный цикл: выкатка, контроль, откат при проблеме.

Выкатываем новую версию

Меняем образ в манифесте на my-backend:1.1 и применяем. Можно и командой set image:

kubectl set image deployment/backend api=my-backend:1.1
kubectl rollout status deployment/backend

Вывод:

Waiting for deployment "backend" rollout to finish: 1 out of 2 new replicas updated...
deployment "backend" successfully rolled out

Kubernetes поднял один новый под, дождался готовности (по readiness-пробе!), погасил старый, затем повторил для второго. Всё это время хотя бы один под обслуживал запросы.

Что если новая версия сломана

Допустим, 1.1 падает в CrashLoopBackOff. Хорошая новость: благодаря readiness-пробе битые поды не попадают в балансировку, и старые ещё работают. Смотрим историю и откатываемся:

kubectl rollout history deployment/backend

Вывод:

REVISION  CHANGE-CAUSE
1         <none>
2         <none>
kubectl rollout undo deployment/backend

Вывод:

deployment.apps/backend rolled back

Команда вернула предыдущую ревизию (1.0), снова через rolling update. Можно откатиться и на конкретную ревизию:

kubectl rollout undo deployment/backend --to-revision=1

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

По умолчанию стратегия — RollingUpdate с параметрами maxSurge (сколько лишних подов можно поднять сверх нормы) и maxUnavailable (сколько можно временно потерять). Их настраивают для баланса скорости и безопасности:

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1            # +1 под во время выкатки
      maxUnavailable: 0      # не терять ни одного готового

С maxUnavailable: 0 выкатка идёт максимально безопасно: новый под поднимается прежде, чем гасится старый.

КомандаДействие
kubectl set imageсменить образ (запустить обновление)
kubectl rollout statusследить за выкаткой
kubectl rollout undoоткатиться назад
--to-revision=Nоткат на конкретную ревизию

Итог

  • Обновление = смена образа + apply; кластер делает rolling update сам.
  • readiness-проба не пускает битые поды в трафик во время выкатки.
  • rollout undo быстро возвращает рабочую версию.
Проверьте себя
1. Как запустить обновление образа Deployment одной командой?
Akubectl scale
Bkubectl set image deployment/backend api=my-backend:1.1
Ckubectl delete
Dkubectl logs
2. Почему битые поды новой версии не ломают сервис во время выкатки?
AОни вообще не создаются
Breadiness-проба не пускает неготовые поды в балансировку
CKubernetes отключает Service
DСтарые поды удаляются первыми
3. Как откатиться на конкретную ревизию?
Akubectl rollout undo --to-revision=N
Bkubectl scale --replicas=N
Ckubectl set image --revision=N
Dkubectl delete revision N
Поддержать проект