Как организовать обновление системы с CI/CD и Kubernetes с учетом надежности и нагрузки
Что проверяют
Понимаете ли вы, что надёжное обновление складывается из трёх частей: пайплайн, стратегия выката в Kubernetes и поведение самого Go-сервиса при остановке. Следом обычно спрашивают, откуда во время выката берутся 502 и как откатиться.
Как отвечать
Пайплайн:
- проверки:
go vet,golangci-lint,go test -race, интеграционные тесты; - образ: многоэтапная сборка, статический бинарник (
CGO_ENABLED=0) в distroless, тег по SHA коммита, а неlatest; - доставка: GitOps через Argo CD или Flux, где откат это возврат коммита.
Выкат:
- RollingUpdate:
maxSurgeиmaxUnavailable, по умолчанию оба 25%. Под нагрузкой разумноmaxUnavailable: 0, тогда мощность не проседает, но в кластере нужен запас под лишние поды; - пробы: readiness решает, идёт ли трафик на под, liveness перезапускает зависший.
progressDeadlineSecondsне даёт выкату молча застрять; - канарейка: Argo Rollouts или Flagger переводят часть трафика и откатывают сами, если в Prometheus растут ошибки или p99;
- устойчивость:
PodDisruptionBudget, HPA, заданныеrequestsиlimits.
Go-часть, которую часто упускают: сервис ловит SIGTERM через signal.NotifyContext, начинает отвечать «не готов», ждёт несколько секунд, пока под уберут из эндпоинтов, и вызывает http.Server.Shutdown(ctx), дорабатывая текущие запросы. Всё это должно уложиться в terminationGracePeriodSeconds, по умолчанию 30 секунд. Задайте GOMEMLIMIT чуть ниже лимита памяти контейнера; с Go 1.25 рантайм сам учитывает CPU-лимит cgroup при выборе GOMAXPROCS.
Миграции базы по схеме expand/contract: старая и новая версии работают одновременно, и схема должна подходить обеим.
Где спотыкаются
Не делают graceful shutdown. Процесс завершается сразу, а балансировщик ещё пару секунд шлёт на него запросы.
Проверяют в liveness базу или соседние сервисы. Упала база, и Kubernetes перезапускает все поды разом.
Катят миграцию, ломающую старую версию, например переименование колонки. Во время RollingUpdate старые поды начинают падать, а откат образа уже не спасает.