Можно ли откатить Deployment в Kubernetes
Что проверяют
Знаете ли вы, где Kubernetes хранит историю версий и что именно откатывает rollout undo. Следом спрашивают, откатится ли вместе с образом конфигурация и миграция базы и как настроить автоматический откат.
Как отвечать
Да. Каждое изменение .spec.template создаёт новый ReplicaSet, а старые остаются с нулём реплик. Они и есть история ревизий.
- посмотреть историю:
kubectl rollout history deployment/app, детали ревизии через--revision=3. Причину изменения показывает аннотацияkubernetes.io/change-cause, флаг--recordдля неё устарел; - откатиться:
kubectl rollout undo deployment/appна предыдущую,--to-revision=3на конкретную; - следить за процессом:
kubectl rollout status deployment/app; - глубина истории:
spec.revisionHistoryLimit, по умолчанию 10. Поставите 0, и откатываться будет не к чему.
Откат это обычный rollout в обратную сторону по стратегии Deployment. При RollingUpdate с настроенными readinessProbe и maxUnavailable он проходит без простоя, при Recreate сервис на время ляжет.
Главное ограничение: откатывается только шаблон пода. Число реплик, содержимое ConfigMap и Secret, Service, Ingress и схема базы остаются как есть. Если новая версия прогнала несовместимую миграцию, старый код может не подняться, поэтому миграции делают в два шага по схеме expand/contract.
Автоматического отката в самом Kubernetes нет. При превышении progressDeadlineSeconds (по умолчанию 600) Deployment получает условие Progressing=False с причиной ProgressDeadlineExceeded, и больше ничего не происходит. Автоматику по метрикам дают Argo Rollouts или Flagger, для Helm-релизов есть helm rollback. В GitOps откатываются через revert в репозитории.
Где спотыкаются
Считают, что rollout undo вернёт и старый ConfigMap. Если конфиг монтируется по одному и тому же имени, старая версия запустится с новым конфигом.
Делают kubectl rollout undo в кластере под Argo CD с автосинхронизацией и через минуту снова видят сломанную версию: контроллер вернул состояние из Git.
Не могут объяснить, почему откатиться не к чему: revisionHistoryLimit: 0 или нужные ревизии уже вытеснены частыми деплоями.