RollingUpdate: как maxSurge и maxUnavailable влияют на доступность и ресурсы
У приложения четыре реплики. Обновление создало новый Pod, который остался Pending, а старые продолжают работать. Это может быть ожидаемым следствием выбранной стратегии: Deployment сохраняет доступность, пока не получит готовую замену. Чтобы понять паузу, нужно одновременно читать ограничения обновления и состояние новых Pod.
Считаем две независимые границы
maxSurge задаёт допустимое число дополнительных реплик сверх желаемого replicas. maxUnavailable ограничивает число недоступных реплик в ходе обновления. Проценты считаются от желаемого числа: surge округляется вверх, unavailable — вниз. Для replicas: 4 и 25% получаются одна дополнительная и одна допустимая недоступная реплика. Для replicas: 3 те же значения дают surge 1 и unavailable 0.
spec:
replicas: 3
minReadySeconds: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0Это фрагмент Deployment, а не полный объект. Он допускает дополнительную реплику и требует сохранять три доступные. minReadySeconds заставляет новую реплику оставаться Ready непрерывно десять секунд, прежде чем она считается доступной. Сама readiness probe должна проверять полезную готовность приложения; неверная проверка позволяет заменить старые Pod слишком рано.
Почему запас по ресурсам обязателен
При maxUnavailable: 0 сначала нужна новая доступная реплика, и только затем освобождается место старой. Если на узлах не помещается дополнительный Pod с его requests, обновление может ждать бесконечно долго относительно ожиданий оператора. Уменьшение CPU limit не создаёт место, когда scheduler отказывает по request. Проверьте события конкретного нового Pod, чтобы отличить дефицит места от ошибки запуска.
kubectl -n demo get deployment api -o yaml
kubectl -n demo get replicasets -l app=api
kubectl -n demo get pods -l app=api -o wide
kubectl -n demo describe pod api-new-exampleНе считайте replicas + maxSurge жёсткой верхней границей всех видимых процессов в каждый момент. Удаляющиеся Pod могут ещё завершать запросы в течение terminationGracePeriodSeconds, а контроллер уже создаёт замену. Они продолжают расходовать ресурсы. Долгое корректное завершение приложения увеличивает необходимый запас, хотя желаемые активные реплики соответствуют стратегии.
Доступная реплика и успешный запрос
Readiness определяет включение Pod в обычный сервисный трафик, но не доказывает совместимость новой версии со схемой базы и соседними сервисами. Во время RollingUpdate старый и новый код работают одновременно. Миграция, которая сразу удаляет старое поле, может сломать ещё обслуживающие трафик реплики. Подготовьте совместимый переход и проверочный запрос через обычный вход приложения.
kubectl -n demo rollout status deployment/api --timeout=180s kubectl -n demo describe deployment api
Timeout этой CLI-команды ограничивает ожидание клиента. Он не отменяет обновление и не возвращает предыдущую версию. Если Deployment превысил progressDeadlineSeconds, контроллер сообщает отсутствие прогресса через condition Progressing с причиной ProgressDeadlineExceeded; автоматический откат из этого факта не следует. После тайм-аута сохраните condition и события, затем выберите исправление.
Выбираем изменение с понятной ценой
Если нужна непрерывная доступность и есть место, сохраняйте unavailable: 0 и обеспечьте ресурс для surge. Если приложение допускает снижение числа доступных реплик, положительный maxUnavailable позволяет освобождать место раньше. Такое решение уменьшает доступную ёмкость сервиса во время релиза, поэтому сравните его с нагрузкой и временем запуска. Одновременно установить обе границы в ноль нельзя.
Для маленького Deployment используйте абсолютные числа, когда проценты скрывают смысл. Одна реплика с maxUnavailable: 1 допускает полный перерыв; maxUnavailable: 0 и surge: 1 требуют места для второй. У трёх реплик 25% unavailable округляется в ноль, что часто удивляет автора конфигурации. Пересчитайте политику после изменения replicas.
Завершённая проверка включает доступные реплики, отсутствие необъяснённого Pending и успешный бизнес-запрос. Сохраните расчёт округления и длительность старта. При следующем увеличении replicas пересчитайте запас и проверьте, что он помещается на допустимых узлах.
Ещё по теме
- Drain узла остановился на PodDisruptionBudget: как разобраться в ограничении
- NetworkPolicy закрыла исходящий трафик: как сохранить DNS и нужные подключения
Продолжить изучение
Хотите увереннее разворачивать приложения и разбирать сбои в кластере? Сети, конфигурация, хранилища и обновления входят в программу «Kubernetes с нуля до PRO».
Продолжить на практике
- Kubernetes с нуля до PRO ↗
Разворачивайте и сопровождайте приложения в Kubernetes: от первого Pod до релизов, сетей, хранилищ, масштабирования и диагностики. Итоговый проект — сервис с базой данных, мониторингом и проверенным откатом.
