Настройка Rolling Update в Kubernetes: практическая настройка maxSurge и maxUnavailable для обновлений без простоя | AdminWiki
Timeweb Cloud — сервера, Kubernetes, S3, Terraform. Лучшие цены IaaS.
Попробовать

Настройка Rolling Update в Kubernetes: практическая настройка maxSurge и maxUnavailable для обновлений без простоя

04 апреля 2026 8 мин. чтения

Rolling Update — это стратегия обновления по умолчанию для Deployment в Kubernetes, которая позволяет обновлять версию вашего приложения без простоев. Вместо одновременной остановки всех подов Kubernetes постепенно заменяет старые экземпляры на новые, сохраняя доступность сервиса. Это похоже на ремонт пола в комнате, где вы заменяете плитки по одной, чтобы по полу можно было продолжать ходить. В этой статье вы получите готовые YAML-манифесты, научитесь настраивать ключевые параметры maxSurge и maxUnavailable для разных сценариев и освоите мониторинг процесса и откат. Информация актуальна для Kubernetes версий 1.25+ и основана на актуальных практиках 2026 года.

Что такое RollingUpdate и как он работает в Kubernetes

Стратегия RollingUpdate — это основной механизм безопасного обновления приложений, управляемых через ресурс Deployment. Когда вы изменяете образ контейнера в спецификации Deployment (например, через kubectl set image или обновляя манифест в Git), контроллер развертывания не удаляет все существующие поды сразу. Вместо этого он создает новые поды с обновленной версией и, после их успешного запуска и прохождения проверок готовности (readinessProbe), поочередно удаляет старые. Этот процесс гарантирует, что в любой момент времени минимальное количество подов, определенное настройками, остается доступным для обработки трафика. Более подробно о механизмах обновления и версионирования в кластере можно узнать из статьи о безопасной миграции CRD в production.

Для глубокого понимания процесса важно знать, что Kubernetes строго следует заданным в манифесте правилам. Вся логика описана в официальной документации, но наша задача — перевести её на язык практических шагов и примеров, которые работают в реальных кластерах.

Ключевые параметры: maxSurge и maxUnavailable. Практическая настройка

Точное поведение Rolling Update контролируется двумя параметрами в блоке spec.strategy.rollingUpdate:

  • maxSurge: Определяет максимальное количество подов, которое может быть создано сверх желаемого числа реплик (replicas) во время обновления. Это позволяет запускать новые версии параллельно со старыми, ускоряя процесс. Значение может быть абсолютным числом (например, 1) или процентом от replicas (например, '25%'). Пример: при replicas=4 и maxSurge=1 общее количество подов в пике обновления может достигать 5.
  • maxUnavailable: Определяет максимальное количество подов, которые могут быть недоступны (удалены или еще не запущены) во время обновления. Этот параметр напрямую влияет на минимальную доступность сервиса. Значение также задается числом или процентом (включая 0). Пример: при replicas=4 и maxUnavailable=1 как минимум 3 пода должны оставаться работоспособными в любой момент.

Баланс между этими параметрами — это компромисс между скоростью обновления, нагрузкой на ресурсы кластера и требуемым уровнем доступности.

Пример базового Deployment с настройками RollingUpdate

Ниже приведен готовый YAML-манифест Deployment для условного приложения myapp. Скопируйте его, измените имя образа и примените в своем кластере для тестирования.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 3
  strategy:
    type: RollingUpdate  # Тип стратегии — обязательное поле
    rollingUpdate:
      maxSurge: 1        # Можно создать 1 дополнительный под
      maxUnavailable: 0  # Ни один под не должен стать недоступным
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp-container
        image: myregistry.com/myapp:v1.2.3 # Замените на ваш образ
        ports:
        - containerPort: 8080
        readinessProbe:  # Критично для корректного RollingUpdate!
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5

Обратите внимание на блок strategy и обязательность настройки readinessProbe. Без пробы готовности Kubernetes не сможет определить, когда новый под готов принимать трафик, и обновление может «зависнуть». Если вы хотите глубже понять, как контроллеры обрабатывают ресурсы, полезным будет гайд по созданию операторов и контроллеров Kubernetes.

Как параметры влияют на процесс обновления: визуализация

Рассмотрим пошаговый сценарий для Deployment с конфигурацией из примера выше (replicas=3, maxSurge=1, maxUnavailable=0).

  1. Шаг 1: Запускается обновление (например, изменяется тег образа). Так как maxSurge=1, Kubernetes может создать один новый под, превысив общее количество в 3. Создается Pod (новый, v1.2.4). Теперь в кластере 4 пода: 3 старых (v1.2.3) и 1 новый.
  2. Шаг 2: Контроллер ждет, пока новый под пройдет проверку readinessProbe и перейдет в состояние Ready.
  3. Шаг 3: После успешного запуска нового пода, так как maxUnavailable=0, Kubernetes удаляет один из старых подов. Теперь в кластере 3 пода: 2 старых (v1.2.3) и 1 новый (v1.2.4).
  4. Шаг 4-6: Процесс повторяется: создается еще один новый под (всего 4), после его готовности удаляется второй старый, и так далее, пока все 3 пода не будут обновлены.

Наблюдать за этим процессом в реальном времени можно с помощью команд:

# Отслеживание изменения состояния подов
kubectl get pods -l app=myapp -w

# Мониторинг статуса обновления Deployment
kubectl rollout status deployment/myapp-deployment

Выбор оптимальных значений maxSurge и maxUnavailable для разных сценариев

Не существует универсальных значений. Выбор зависит от требований к доступности, доступных ресурсов в кластере и допустимой скорости развертывания. Используйте эту таблицу как отправную точку для принятия решений.

Сценарий Рекомендуемые значения Обоснование и компромиссы
Критичные production-сервисы (High Availability) maxUnavailable: 0
maxSurge: 1
Приоритет: нулевой простой. Гарантирует, что все реплики доступны во время обновления. Недостаток: обновление происходит медленнее всего, так как новые поды запускаются строго по одному. Для Deployment с большим числом реплик (например, 10) можно установить maxUnavailable: 1, чтобы ускорить процесс, сохранив высокую доступность.
Среда с ограниченными ресурсами (CPU/Memory) maxSurge: 0
maxUnavailable: "25%"
Приоритет: не превышать лимиты ресурсов нод. Запрещает создание дополнительных подов, предотвращая исчерпание ресурсов. Обновление происходит за счет временного снижения количества работающих реплик на 25%. Это замедляет процесс и снижает доступность, но защищает кластер от перегрузки.
Быстрое обновление тестовых/разработческих сред maxUnavailable: "50%"
maxSurge: "100%"
Приоритет: скорость развертывания. Позволяет быстро заменить до половины подов одновременно и запустить все новые реплики параллельно со старыми. Это самый быстрый, но и самый рискованный режим, недопустимый для production.
Канареечные (canary) развертывания Использование maxSurge для запуска 1-2 новых подов параллельно Приоритет: безопасное тестирование новой версии. Настройте maxSurge: 1 при replicas: 5. При обновлении будет создан один новый под, который будет обслуживать часть трафика вместе со старыми. Это позволяет проверить стабильность новой версии перед полным rollout.

Мониторинг обновления и откат (rollback) при проблемах

Даже с идеальными настройками обновление может пойти не по плану. Kubernetes предоставляет инструменты для контроля и быстрого отката.

Команды для мониторинга:

  • kubectl rollout status deployment/<имя> — показывает текущую стадию обновления и завершается при его окончании (успешном или неудачном).
  • kubectl get pods --show-labels — помогает визуально отделить поды новой версии (по label версии образа) от старых.
  • kubectl describe deployment <имя> — выводит подробную информацию, включая события (Events), которые часто содержат причину сбоя.

Команды для отката:

  • kubectl rollout undo deployment/<имя> — откатывает Deployment к предыдущей ревизии. Это запускает новый Rolling Update, но уже с предыдущей версией образа.
  • kubectl rollout history deployment/<имя> — показывает историю всех изменений Deployment с номерами ревизий.

Для эффективной диагностики проблем используйте алгоритм: 1) проверьте статус подов (kubectl get pods), 2) изучите описание упавшего пода (kubectl describe pod <имя-пода>) на наличие ImagePullBackOff или CrashLoopBackOff, 3) проверьте логи нового пода (kubectl logs <имя-пода>). Подробнее о систематической отладке ресурсов в Kubernetes читайте в статье «Полная диагностика Custom Resources в Kubernetes».

Настройка revisionHistoryLimit для возможности отката

По умолчанию Kubernetes хранит историю ревизий Deployment (старые ReplicaSet), что позволяет делать откат. Количество хранимых ревизий контролируется параметром revisionHistoryLimit в спецификации Deployment. Если он не задан или равен 0, откат будет невозможен.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 3
  revisionHistoryLimit: 10  # Хранить историю 10 последних ревизий
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  # ... остальная спецификация

Рекомендуемое значение — от 5 до 10. Хранение большего числа ревизий увеличивает нагрузку на etcd, но дает больше точек для отката.

Интеграция RollingUpdate в CI/CD пайплайн

Настройка манифестов — это только половина дела. В рабочем процессе обновление почти всегда инициируется автоматически из пайплайна CI/CD.

Классический подход (императивный): В вашем пайплайне Jenkins, GitLab CI или GitHub Actions добавляется этап, который выполняет команду обновления образа. Это триггерит RollingUpdate в соответствии с настройками Deployment.

# Пример этапа в GitLab CI .gitlab-ci.yml
deploy:
  stage: deploy
  script:
    - kubectl set image deployment/myapp-deployment myapp-container=myregistry.com/myapp:$CI_COMMIT_TAG
    - kubectl rollout status deployment/myapp-deployment --timeout=300s

GitOps подход (декларативный): При использовании инструментов вроде ArgoCD или Flux CD вы вообще не выполняете команды kubectl напрямую. Вместо этого вы обновляете тег образа в YAML-манифесте в Git-репозитории (например, через PR). АргоCD обнаруживает изменение в Git и автоматически синхронизирует состояние кластера, запуская процесс RollingUpdate. В этом подходе критически важна корректная настройка readinessProbe и livenessProbe, так как они служат сигналом для инструментов о успешности деплоя. Для управления сложными развертываниями в GitOps часто используется Helm, который также поддерживает стратегии обновления.

Частые проблемы при Rolling Update и их решение

Разберем типичные кейсы, когда обновление не проходит гладко.

1. Обновление «зависло» (Rollout hangs). Команда kubectl rollout status не завершается долгое время.
Причины и решение:

  • Некорректная readinessProbe: Новый под никогда не переходит в состояние Ready. Проверьте логи пода и убедитесь, что эндпоинт /health (или другой) возвращает успешный статус. Возможно, нужно увеличить initialDelaySeconds.
  • Нехватка ресурсов (Pending state): Новый под не может быть запланирован на ноду из-за недостатка CPU или памяти. Проверьте kubectl describe pod <имя-нового-пода> и события кластера (kubectl get events).
  • Ошибка в новом образе (CrashLoopBackOff): Приложение в новом контейнере падает сразу после запуска. Изучите логи пода (kubectl logs --previous может показать логи предыдущей попытки запуска).

2. ImagePullBackOff. Кластер не может скачать новый образ.
Причины: Неверное имя образа, отсутствие прав доступа к container registry, проблемы с сетью. Убедитесь, что используемый ServiceAccount имеет необходимые imagePullSecrets.

3. Долгое обновление. Процесс идет, но очень медленно.
Причины: Большой размер образа (долгая загрузка), длительная инициализация приложения внутри контейнера.
Возможное решение: Увеличить maxSurge, чтобы запускать несколько новых подов параллельно, тем самым распараллелив этап загрузки образа. Либо оптимизировать образ и процесс запуска приложения.

Помните, что RollingUpdate — не единственная стратегия оркестрации контейнеров. Для некоторых сценариев, особенно в менее сложных инфраструктурах, может быть полезна альтернатива в виде Docker Swarm, которая также поддерживает rolling updates, но с иной философией управления.

Поделиться:
Сохранить гайд? В закладки браузера