Статьи

Одна сборка, продвижение по digest: пайплайн поставки с откатом

Эталонный путь поставки, где артефакт, проверенный в staging, — ровно тот же, что в продакшене, а откат — это повторный деплой предыдущего digest.

Примеры обобщённые и иллюстративные. Они не взяты из среды какого-либо клиента: подстройте пороги и параметры под свою систему.

Проблема пересборки под каждое окружение

Пайплайны, которые пересобирают приложение для каждого окружения, тестируют один артефакт, а выкатывают другой. Зависимости разрешаются иначе, базовый образ меняется, флаг сборки отличается — и версия в продакшене нигде не тестировалась. Собирайте один раз, дайте артефакту неизменяемый идентификатор и продвигайте именно его.

Эталонный путь

Обобщённый путь от коммита до продакшена. Каждый этап либо передаёт тот же артефакт дальше, либо останавливает его.

  1. 01КоммитPull request с ревью и обязательными проверками.
  2. 02СборкаОдна сборка на коммит; образ публикуется, его digest фиксируется.
  3. 03ПроверкаТесты, сканирование зависимостей и образа, подпись.
  4. 04StagingДеплой digest; smoke- и интеграционные тесты.
  5. 05ПродакшенТот же digest, постепенная выкатка.
  6. 06НаблюдениеБюджет ошибок и алерты решают: продолжать или откатывать.

Digest, а не теги

Теги вроде latest или v2 — изменяемые ярлыки; digest (sha256:…) — это хеш содержимого образа. Манифесты деплоя должны ссылаться на digest, а пайплайн продвигает окружение, меняя это единственное значение, — в идеале коммитом в репозиторий деплоя, чтобы каждый релиз был проверенным и обратимым изменением.

# build once and record the digest
docker buildx build --push --metadata-file meta.json \
  -t registry.example.com/api:"$GIT_SHA" .
DIGEST=$(jq -r '."containerimage.digest"' meta.json)

# promote: every environment receives the same digest
kustomize edit set image api=registry.example.com/api@"$DIGEST"

Изменения базы данных: расширить, затем сузить

Откатить код легко, только если схема по-прежнему подходит предыдущей версии. Разбейте несовместимые миграции на шаги, каждый из которых совместим с работающим кодом: добавьте новую колонку или таблицу, выкатите код, который пишет в обе, заполните данные, переключите чтение и лишь в одном из следующих релизов удалите старую структуру.

Постепенная поставка и откат

  • Сначала выкатывайте на часть трафика или реплик и сравнивайте долю ошибок и задержку с текущей версией.
  • Привяжите решение к SLO: высокий burn rate во время выкатки автоматически останавливает продвижение.
  • Откат — это повторный деплой предыдущего digest по тому же, уже проверенному пути, а не хотфикс, написанный под давлением.
  • Держите конфигурацию и секреты вне образа, чтобы один и тот же артефакт работал во всех окружениях.
Контакты

Нужно второе мнение о вашей системе?

Пришлите короткое описание системы. Опытный инженер ответит письменно в течение рабочего дня.

Обсудить инфраструктуру