← Kubernetes: Kustomize и Helm
6 мин · средне · Урок 9 из 9

Helm: upgrade и rollback

Ревизии релиза, история в Secret, откат одной командой и почему upgrade иногда теряет ранее заданные values.

Установленный релиз не переустанавливают. Его меняют командой helm upgrade, и Helm 3 ведёт для него историю: каждое изменение это новая ревизия. Если версия сломалась, откат делается одной командой, без ручного восстановления манифестов.

Upgrade

helm upgrade web ./myapp -n demo -f values/prod.yaml --set-string image.tag=1.26

Helm пересобирает шаблоны с новыми значениями, сравнивает результат с предыдущей ревизией и применяет разницу. Релиз web получает ревизию 2, прежняя остаётся в истории.

Практически всегда пишут с флагом --install:

helm upgrade --install web ./myapp -n demo -f values/prod.yaml

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

Upgrade без тех же -f и --set, что были при установке, теряет прежние переопределения: реплики возвращаются к дефолту, образ к дефолтному тегу. Лечится повторной передачей тех же файлов values или флагом --reuse-values.

История ревизий

helm history web -n demo

Вывод покажет номер ревизии, дату, статус (deployed, superseded, failed), версию чарта и описание: install, upgrade или rollback.

Каждая ревизия лежит отдельным Secret в namespace релиза, с именем sh.helm.release.v1.web.v2. Оттуда же берутся значения конкретной ревизии:

helm get values web -n demo --revision 1

Rollback

helm rollback web 1 -n demo

Релиз возвращается к состоянию ревизии 1. Без номера Helm откатывает на одну ревизию назад.

Важная деталь: откат не стирает историю. Он добавляет новую ревизию, повторяющую старое состояние. После отката с ревизии 2 на ревизию 1 в истории появится ревизия 3 с описанием rollback. Логика та же, что у kubectl rollout undo, только на уровне всего релиза, а не одного Deployment.

rev 1  install
rev 2  upgrade    сломалось
rev 3  rollback   копия rev 1

Сколько ревизий хранить

Каждая ревизия занимает отдельный Secret. По умолчанию helm upgrade хранит 10 последних и подчищает лишние. Лимит меняется флагом:

helm upgrade web ./myapp -n demo --history-max 3

Значение 0 снимает ограничение. На активно обновляемом релизе это оборачивается сотнями Secret, поэтому лимит обычно оставляют.

Ждать результата и откатываться автоматически

По умолчанию helm upgrade завершается, как только манифесты приняты API-сервером. Дошёл ли rollout до конца, Helm не проверяет.

helm upgrade web ./myapp -n demo --atomic --timeout 5m

--atomic включает ожидание готовности объектов и автоматический откат на предыдущую ревизию, если за отведённое время что-то не поднялось. Для пайплайнов это самый полезный флаг: неудачная выкатка не оставляет релиз в полусломанном состоянии.

Отдельно есть --wait (ждать без отката) и --cleanup-on-fail (удалять объекты, созданные неудачным обновлением).

Что обычно ломается

Прерванное обновление оставляет релиз в статусе pending-upgrade. Следующая команда откажется работать с сообщением про уже идущую операцию. Выход - откатиться на последнюю рабочую ревизию через helm rollback.

Неизменяемые поля не переживают upgrade. Смена spec.selector у Deployment или типа Secret вызовет ошибку от API-сервера. Такие объекты приходится удалять и создавать заново.

Rollback возвращает манифесты, но не данные. Миграция базы, выполненная новой версией приложения, останется применённой, и старый код может с ней не завестись. Обратная совместимость схемы БД - забота приложения, а не Helm.

Ревизия, помеченная failed, всё равно занимает номер. В истории попадаются подряд идущие неудачные ревизии, и откатываться нужно на последнюю со статусом superseded или deployed, а не просто на предыдущий номер.

Домашка

Теорию закрепляет задание на своём кластере: 2 шага с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.

./run.sh start k8s-helm-upgrade-rollback     # развернуть стартовое состояние
./run.sh verify k8s-helm-upgrade-rollback    # проверить текущий шаг

Коротко

Прошли материал до конца? Отметьте урок пройденным.