Автоматическое масштабирование
Автоматическое масштабирование (autoscaling) позволяет динамически изменять объем ресурсов кластера Managed Kubernetes в зависимости от нагрузки. Благодаря этому вы можете не резервировать дополнительные вычислительные ресурсы заранее — они будут предоставлены при увеличении нагрузки и автоматически освободятся при падении нагрузки.
При горизонтальном масштабировании изменяется количество подов и узлов кластера, а при вертикальном — количество выделенных ресурсов (vCPU и RAM) для подов.
Кластер Managed Kubernetes поддерживает три механизма автоматического масштабирования:
- Cluster Autoscaler (CA) — для изменения количества узлов в группе.
- Horizontal Pod Autoscaler (HPA) — для изменения количества подов на узле.
- Vertical Pod Autoscaler (VPA) — для выделения дополнительных ресурсов vCPU и RAM подам.
Вы можете использовать все виды автоматического масштабирования одновременно. При этом для Vertical Pod Autoscaler существуют ограничения по совместимости с другими механизмами автоматического масштабирования.
Подробнее о механизмах автоматического масштабирования см. в документации Kubernetes.
Cluster Autoscaler
Cluster Autoscaler следит за нагрузкой на узлы и при необходимости изменяет их количество в указанных пределах. Включить Cluster Autoscaler и задать пределы для количества узлов можно при создании или изменении кластера.
Чтобы развернуть Cluster Autoscaler в вашем кластере, воспользуйтесь инструкцией.
Принцип работы Cluster Autoscaler
Cluster Autoscaler при работе опирается на следующие метрики:
- запросы ресурсов для приложений:
pod.spec.containers[].container.resources.requests.cpuиpod.spec.containers[].container.resources.requests.memory. - ресурсы узла, доступные для использования подами:
status.allocatable.cpuиstatus.allocatable.memory.
Cluster Autoscaler увеличит количество узлов, если в кластере есть поды, создание которых не удалось запланировать ни на одном из существующих узлов (статус пода — Unschedulable). При этом Cluster Autoscaler не учитывает метрики узлов, а только следит за тем, чтобы развертывание всех подов в кластере было успешно запланировано.
Cluster Autoscaler уменьшит количество узлов, когда появятся незанятые (unused) узлы. Узел считается незанятым, если одновременно выполняются следующие условия:
- Сумма запросов (
requests) к vCPU и RAM для всех подов (включая поды DaemonSet и Mirror Pods) составляет менее 50% от доступных для использования (allocatable) ресурсов узла. - Все поды, запущенные на этом узле, могут быть перемещены на другие узлы. Это правило не включает в себя поды, которые выполняются на всех узлах по умолчанию — например, статические поды или поды DaemonSet.
Если узел считается незанятым более 10 минут, он будет автоматически удален. Чтобы снизить риск создания новых незапланированных подов, Cluster Autoscaler удаляет незанятые узлы по одному. Следующий незанятый узел может быть удален сразу после предыдущего, если он также был не занят более 10 минут.
При завершении работы незанятого узла все его поды будут автоматически перенесены на другие узлы. Cluster Autoscaler помечает поды, как удаленные, и устанавливает на узел ограничение (taint) — на нем больше не будут планироваться новые поды. Узел будет принудительно удален спустя 10 минут после удаления подов, даже если какие-то поды к этому времени не успевают автоматически остановиться.
Если Cluster Autoscaler включен на нескольких группах узлов, группа для увеличения размера будет выбрана случайным образом.
Значения предустановленных настроек Cluster Autoscaler
| Имя настройки | Описание | Значение |
|---|---|---|
scale-down-utilization-threshold | Отношение суммы запросов (requests) для всех подов, запущенных на узле, к доступным (allocatable) ресурсам узла, ниже которого узел рассматривается как кандидат на удаление | 0,5 |
scale-down-unneeded-time | Задержка между двумя масштабированиями вниз | 10 минут |
scale-down-delay-after-add | Задержка масштабирования вниз после масштабирования вверх | 10 минут |
scale-down-delay-after-failure | Задержка после сбоя масштабирования вниз | 3 минуты |
unremovable-node-recheck-timeout | Тайм-аут повтора попытки удалить узел, который не удалось удалить ранее | 5 минут |
max-empty-bulk-delete | Максимальное количество узлов для одновременного удаления при масштабировании вниз | 10 |
expander | Стратегия выбора группы узлов для масштабирования | random |
Здесь:
- масштабирование вверх — увеличение количества узлов в группе в результате роста нагрузки;
- масштабирование вниз — уменьшение количества узлов в группе в результате перехода некоторых узлов в статус
unused.
Правила удаления и добавления узлов при работе Cluster Autoscaler
Правила удаления узлов
Cluster Autoscaler не будет удалять узел, если на нем существуют:
поды, ограниченные с помощью PodDisruptionBudget;
поды в пространстве имен
kube-system, созданные не под управлением контроллеров DaemonSet, ReplicaSet, Deployment или StatefulSet;поды с local-storage, использующие тома hostPath, а также временные тома emptyDir (
spec.volumes[].volume.emptyDir.medium=Memory);поды, которые не могут быть расселены куда-либо из-за ограничений — например, при недостатке ресурсов или отсутствии узлов, подходящих по селекторам
affinityилиanti-affinity.Примечание
NodeAffinity учитывается только в режиме requiredDuringSchedulingIgnoredDuringExecution.
Работа с Priority и Preemption
Cluster Autoscaler учитывает приоритет (Priority) и вытеснение (Preemption) подов:
- Если в кластере есть незапланированные поды с приоритетом ниже 10, новый узел для них не будет добавлен.
- Поды с приоритетом ниже 10, работающие на узле, не препятствуют удалению этого узла.
- Новый узел не будет добавлен, если незапланированный под уже ожидает вытеснения пода с более низким приоритетом.
Обработка нештатных ситуаций
Cluster Autoscaler обрабатывает нештатные ситуации в работе кластера:
- Если количество узлов в группе меньше минимального, новые узлы будут добавлены только когда появятся незапланированные поды.
- Если количество узлов в группе больше максимального, узлы будут удалены только когда перейдут в статус
unused.
Horizontal Pod Autoscaler
Horizontal Pod Autoscaler динамически изменяет количество подов рабочей нагрузки в зависимости от загрузки vCPU. Этот тип масштабирования работает с контролерами StatefulSet, ReplicaSet и Deployment.
Для Horizontal Pod Autoscaler доступны следующие настройки:
cpu-percent— планируемая средняя нагрузка на vCPU для каждого пода, в процентах;minиmax— минимальное и максимальное количество реплик подов.
Чтобы развернуть Horizontal Pod Autoscaler в вашем кластере, воспользуйтесь инструкцией.
Дополнительную информацию о Horizontal Pod Autoscaler см. в документации Kubernetes.
Vertical Pod Autoscaler
Vertical Pod Autoscaler динамически выделяет дополнительные ресурсы vCPU и RAM для подов, если это необходимо для стабильной работы.
Для подов Kubernetes устанавливаются ограничения на vCPU и RAM:
requests— минимальный запрошенный объем ресурсов, который гарантирован поду;limits— максимальный объем ресурсов, который может использовать под.
Под, превысивший значения limits, будет автоматически удален, чтобы избежать троттлинга процессора или ошибок Out of Memory. С помощью Vertical Pod Autoscaler можно отслеживать и автоматически исправлять как проблемы с недостатком ресурсов, так и ситуации с избыточным выделением ресурсов подам.
Для Vertical Pod Autoscaler доступны настройки режима автоматического масштабирования (updateMode):
Off— Vertical Pod Autoscaler предоставляет рекомендации по управлению ресурсами, но не изменяет их.Recreate(по умолчанию) — Vertical Pod Autoscaler применяет рекомендации по ресурсам при создании и обновлении подов. Существующие поды пересоздаются методом вытеснения (Eviction), при этом учитываются правила PodDisruptionBudget.InPlaceOrRecreate— Vertical Pod Autoscaler пытается обновить ресурсы существующих подов «на лету» (без перезапуска). Если это невозможно, он пересоздает под с помощью методаRecreate.Initial— Vertical Pod Autoscaler назначает запросы ресурсов только при создании пода и больше никогда их не изменяет.
Чтобы развернуть Vertical Pod Autoscaler в вашем кластере, воспользуйтесь инструкцией.
Дополнительную информацию о Vertical Pod Autoscaler см. в документации Kubernetes.
Рекомендации по планированию автоматического масштабирования
При использовании оптимальных подходов алгоритм работы автоматического масштабирования будет таким:
- Vertical Pod Autoscaler следит за выделением ресурсов подам, и при необходимости, в фоновом режиме, корректирует их.
- При возникновении пиковой нагрузки Horizontal Pod Autoscaler увеличит количество экземпляров ключевой рабочей нагрузки.
- Если высокая нагрузка сохранится, Cluster Autoscaler увеличит количество узлов в группе.
- Когда нагрузка будет снижена, Horizontal Pod Autoscaler уменьшит количество экземпляров ключевой рабочей нагрузки, а Cluster Autoscaler масштабирует группу узлов до начального уровня.
Используйте эти рекомендации для оптимального планирования вычислительных ресурсов кластера:
- Для ключевой рабочей нагрузки (
workload) укажите необходимые запросы на ресурсы (requests). Это позволит избежать лишних срабатываний Cluster Autoscaler. - Используйте Cluster Autoscaler совместно с Horizontal Pod Autoscaler. Настройте оба механизма масштабирования на работу с ключевыми рабочими нагрузками.
- Перед развертыванием Vertical Pod Autoscaler совместно с другими механизмами масштабирования изучите ограничения. Чтобы избежать конфликта между механизмами масштабирования, выберите режим предоставления рекомендаций (
updateMode = Off) для Vertical Pod Autoscaler, и применяйте рекомендации вручную. - Приводите запросы на ресурсы к значениям, близким к реальному потреблению. Периодически корректируйте эти значения, отслеживайте рост потребления ресурсов.
- Используйте контроллеры Deployment, StatefulSet и DaemonSet для управления репликацией подов. Создавайте не управляемые контроллерами поды только для тестовых задач.
- Изучите метрики Resource Recommendation, которые предоставляет Vertical Pod Autoscaler для контроллеров Deployment, StatefulSet и DaemonSet.
- Не используйте для хранения данных тома hostPath, а также временные тома emptyDir (
spec.volumes[].volume.emptyDir.medium=Memory).