Практическое руководство по настройке Horizontal Pod Autoscaler (HPA) в Kubernetes

Настройте HPA в Kubernetes с помощью запросов ресурсов, метрик, поведения масштабирования, окон стабилизации и команд проверки.

Практическое руководство по настройке Horizontal Pod Autoscaler (HPA) в Kubernetes

Horizontal Pod Autoscaler (HPA) в Kubernetes может поддерживать отзывчивость вашего приложения во время всплесков трафика, но только если метрики и лимиты отражают поведение приложения. Плохо настроенный HPA может масштабироваться слишком поздно, слишком быстро уменьшать количество реплик или вообще не масштабироваться из-за отсутствия запросов ресурсов.

Это руководство покажет вам, как настроить HPA в Kubernetes с помощью CPU, памяти, пользовательских метрик, внешних метрик и элементов управления поведением масштабирования.

Понимание Horizontal Pod Autoscaler (HPA)

HPA автоматически увеличивает или уменьшает количество подов в вашем приложении в соответствии с текущим спросом. Он непрерывно отслеживает указанные метрики и сравнивает их с целевыми значениями. Если наблюдаемая метрика превышает целевое значение, HPA инициирует событие увеличения масштаба; если она падает ниже, он запускает уменьшение масштаба. Эта динамическая настройка гарантирует, что ваше приложение имеет достаточно ресурсов для оптимальной работы без избыточного выделения.

HPA может масштабироваться на основе:

  • Метрики ресурсов: В первую очередь использование CPU и памяти (доступно через API metrics.k8s.io, обычно предоставляемый Kubernetes Metrics Server).
  • Пользовательские метрики: Метрики, специфичные для приложения, предоставляемые через API custom.metrics.k8s.io (например, запросы в секунду, глубина очереди, активные соединения). Обычно для этого требуется адаптер, такой как prometheus-adapter.
  • Внешние метрики: Метрики из источников за пределами кластера, предоставляемые через API external.metrics.k8s.io (например, размер очереди Google Cloud Pub/Sub, длина очереди AWS SQS). Для них также требуется сервер API пользовательских метрик, способный получать внешние метрики.

Предварительные условия для эффективной настройки HPA

Прежде чем углубляться в конфигурации HPA, убедитесь, что выполнены следующие основные условия:

1. Определите точные запросы и лимиты ресурсов

Это, пожалуй, самое важное предварительное условие. HPA сильно зависит от правильно определенных запросов CPU и памяти для расчета процентов использования. Если у пода нет запросов CPU, HPA не может рассчитать его использование CPU, что делает масштабирование на основе CPU невозможным.

  • Запросы: Определите минимальные гарантированные ресурсы для ваших контейнеров. HPA использует эти значения для определения целевого использования на под.
  • Лимиты: Определите максимальные ресурсы, которые может потреблять контейнер. Лимиты предотвращают потребление одним подом чрезмерных ресурсов и влияние на другие поды на том же узле.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: my-image:latest
        resources:
          requests:
            cpu: "200m"  # 20% ядра CPU
            memory: "256Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"

2. Установите Kubernetes Metrics Server

Чтобы HPA мог использовать метрики использования CPU и памяти, в вашем кластере должен быть установлен Kubernetes Metrics Server. Он собирает метрики ресурсов с Kubelet и предоставляет их через API metrics.k8s.io.

3. Наблюдаемость приложения

Для пользовательских или внешних метрик ваше приложение должно предоставлять соответствующие метрики (например, через конечную точку Prometheus), и вам понадобится способ собирать и предоставлять эти метрики API Kubernetes, обычно с помощью адаптера Prometheus или сервера API пользовательских метрик.

Настройка HPA: основные параметры

Давайте рассмотрим базовую структуру манифеста HPA:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

Ключевые параметры:

  • scaleTargetRef: Определяет целевой ресурс (например, Deployment), который будет масштабировать HPA. Укажите его apiVersion, kind и name.
  • minReplicas: Минимальное количество подов, до которого HPA будет уменьшать масштаб. Рекомендуется устанавливать это значение не менее 1 или 2 для обеспечения высокой доступности, даже при нулевой нагрузке.
  • maxReplicas: Максимальное количество подов, до которого HPA будет увеличивать масштаб. Это служит защитой от неконтролируемого масштабирования и ограничивает затраты.
  • metrics: Массив, определяющий метрики, которые должен отслеживать HPA.
    • type: Может быть Resource, Pods, Object или External.
    • resource.name: Для типа Resource указывает cpu или memory.
    • target.type: Для типа Resource, Utilization (процент от запрошенного ресурса) или AverageValue (абсолютное значение).
    • averageUtilization: Для типа Utilization, целевой процент. HPA рассчитывает желаемое количество подов на основе current_utilization / target_utilization * current_pods_count.

Настройка HPA для отзывчивости и стабильности

Помимо базовой конфигурации, HPA предлагает расширенные возможности настройки, особенно с autoscaling/v2 (или v2beta2 в старых версиях), для более детального управления поведением масштабирования.

1. Целевые показатели CPU и памяти (averageUtilization / averageValue)

Установка правильного целевого использования имеет решающее значение. Более низкое целевое значение означает более раннее масштабирование (более отзывчивое, потенциально более дорогое), в то время как более высокое целевое значение означает более позднее масштабирование (менее отзывчивое, потенциально более дешевое, но с риском ухудшения производительности).

  • Как определить оптимальные цели: Нагрузочное тестирование и профилирование — ваши лучшие друзья. Постепенно увеличивайте нагрузку на ваше приложение, отслеживая использование ресурсов и показатели производительности (задержка, частота ошибок). Определите использование CPU/памяти, при котором производительность вашего приложения начинает ухудшаться. Установите цель HPA ниже этого порога, обычно в диапазоне 60-80% для CPU.
  • Балансирование: Стремитесь к цели, которая оставляет достаточный запас для неожиданных всплесков, но не настолько низкой, чтобы вы постоянно были избыточно обеспечены ресурсами.

2. Поведение масштабирования (поле behavior)

Введенное в HPA autoscaling/v2, поле behavior обеспечивает детальный контроль над событиями увеличения и уменьшения масштаба, предотвращая "трепетание" (быстрые циклы увеличения и уменьшения масштаба).

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 60 # Подождать 60 секунд перед следующим увеличением масштаба
      policies:
      - type: Pods
        value: 4
        periodSeconds: 15 # Добавлять максимум 4 пода каждые 15 секунд
      - type: Percent
        value: 100
        periodSeconds: 15 # Или удваивать текущее количество подов каждые 15 секунд (в зависимости от того, что менее ограничительно)
    scaleDown:
      stabilizationWindowSeconds: 300 # Подождать 5 минут перед уменьшением масштаба
      policies:
      - type: Percent
        value: 50
        periodSeconds: 60 # Удалять максимум 50% подов каждые 60 секунд
      selectPolicy: Max # Выбрать политику, которая допускает наибольшее разрешенное изменение при уменьшении масштаба

Конфигурация scaleUp:

  • stabilizationWindowSeconds: Сглаживает рекомендации по масштабированию за последний временной интервал. Увеличение масштаба обычно использует короткое окно, чтобы приложение могло быстро реагировать.
  • policies: Определяет, как добавляются поды во время события увеличения масштаба. Вы можете определить несколько политик, и HPA будет использовать ту, которая допускает наибольшее количество подов (наиболее агрессивное увеличение масштаба).
    • type: Pods: Увеличивает масштаб на фиксированное количество подов. value указывает количество добавляемых подов. periodSeconds определяет временной интервал, в течение которого применяется эта политика.
    • type: Percent: Увеличивает масштаб на процент от текущего количества подов. value — это процент.

Конфигурация scaleDown:

  • stabilizationWindowSeconds: Более критично для scaleDown, указывает, как долго HPA должен наблюдать метрики ниже целевого значения, прежде чем рассматривать уменьшение масштаба. Более длинное окно (например, 300-600 секунд) предотвращает преждевременное уменьшение масштаба во время временных затиший, избегая "холодных стартов" и падений производительности. Это критически важная настройка для стабильных сред.

  • policies: Аналогично scaleUp, определяет, как удаляются поды. HPA использует политику, которая приводит к наименьшему количеству подов (наиболее агрессивное уменьшение масштаба), если selectPolicy имеет значение Min, или политику, которая приводит к наибольшему количеству подов, если selectPolicy имеет значение Max.

    • type: Pods: Удаляет фиксированное количество подов.
    • type: Percent: Удаляет процент текущих подов.
  • selectPolicy: Определяет, какую политику применять, когда определено несколько политик scaleDown. Max используется по умолчанию и выбирает политику, которая допускает наибольшее изменение масштаба. Используйте Min, когда вы хотите более консервативного уменьшения масштаба.

  • Предупреждение: Будьте осторожны с агрессивными политиками scaleDown или короткими stabilizationWindowSeconds для scaleDown. Если ваше приложение имеет длительное время инициализации или обрабатывает состояния соединений, быстрое уменьшение масштаба может привести к перебоям в обслуживании или увеличению задержки для пользователей.

Расширенные метрики и стратегии HPA

Хотя CPU и память распространены, многие приложения лучше масштабируются на основе пользовательских или внешних метрик, которые отражают их фактическую рабочую нагрузку.

1. Пользовательские метрики

Используйте пользовательские метрики, когда CPU/память не являются прямым индикатором нагрузки или узкого места производительности вашего приложения. Примеры: HTTP-запросы в секунду (QPS), активные соединения, длина очереди сообщений, отставание пакетных заданий.

Чтобы использовать пользовательские метрики:

  1. Ваше приложение должно предоставлять эти метрики (например, через экспортер Prometheus).
  2. Разверните адаптер пользовательских метрик (например, prometheus-adapter), который может собирать эти метрики и предоставлять их через API custom.metrics.k8s.io.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa-qps
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 15
  metrics:
  - type: Pods # Или Object, если метрика относится к развертыванию в целом
    pods:
      metric:
        name: http_requests_per_second # Имя метрики, предоставляемой вашим приложением/адаптером
      target:
        type: AverageValue
        averageValue: "10k" # Цель: 10 000 запросов в секунду на под

2. Внешние метрики

Внешние метрики полезны, когда рабочая нагрузка вашего приложения управляется внешней системой, не работающей непосредственно на Kubernetes. Примеры: глубина очереди AWS SQS, отставание топика Kafka, отставание подписки Pub/Sub.

Чтобы использовать внешние метрики:

  1. Вам нужен сервер API пользовательских метрик, который может получать метрики из вашей внешней системы (например, специальный адаптер для AWS CloudWatch или GCP Monitoring).
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-worker-hpa-sqs
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-worker
  minReplicas: 1
  maxReplicas: 20
  metrics:
  - type: External
    external:
      metric:
        name: aws_sqs_queue_messages_visible # Имя метрики из вашего внешнего источника
        selector:
          matchLabels:
            queue: my-queue-name
      target:
        type: AverageValue
        averageValue: "100" # Цель: 100 видимых сообщений в очереди на под

3. Несколько метрик

HPA можно настроить на одновременный мониторинг нескольких метрик. Когда указано несколько метрик, HPA вычисляет желаемое количество реплик для каждой метрики независимо, а затем выбирает наибольшее из этих желаемых количеств реплик. Это гарантирует, что приложение масштабируется достаточно для всех наблюдаемых аспектов нагрузки.

# ... (шаблон HPA)
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: "10k"

Мониторинг и проверка

Эффективная настройка HPA — это итеративный процесс, требующий постоянного мониторинга и проверки:

  • Наблюдайте за событиями HPA: Используйте kubectl describe hpa <hpa-name>, чтобы увидеть статус HPA, события и решения по масштабированию. Это дает ценную информацию о том, почему HPA увеличил или уменьшил масштаб.
  • Отслеживайте метрики и реплики: Используйте свой стек observability (например, Prometheus, Grafana) для визуализации использования ресурсов вашего приложения (CPU, память), пользовательских/внешних метрик и фактического количества реплик подов с течением времени. Соотносите это с изменениями входящей нагрузки.
  • Нагрузочное тестирование: Моделируйте ожидаемые и пиковые нагрузки, чтобы проверить отзывчивость HPA и убедиться, что ваше приложение работает должным образом под нагрузкой. Корректируйте параметры HPA на основе этих тестов.

Лучшие практики настройки HPA

  • Начните с четко определенных запросов/лимитов ресурсов: Они являются основой точного HPA на основе ресурсов. Без них HPA не может эффективно работать для CPU/памяти.
  • Установите реалистичные minReplicas и maxReplicas: minReplicas обеспечивает базовый уровень доступности, в то время как maxReplicas служит предохранительным клапаном от неконтролируемых затрат и истощения ресурсов.
  • Постепенно корректируйте целевое использование: Начните с немного консервативной цели по CPU (например, 60-70%) и итерируйте. Не стремитесь к 100% использованию, так как это не оставляет буфера для задержек или всплесков обработки.
  • Используйте stabilizationWindowSeconds: Необходимо для предотвращения быстрых колебаний масштабирования. Используйте более длинное окно для scaleDown (например, 5-10 минут), чем для scaleUp (например, 1-2 минуты), чтобы обеспечить стабильность.
  • Отдавайте приоритет метрикам, специфичным для приложения: Если CPU или память не коррелируют напрямую с узкими местами производительности вашего приложения, используйте пользовательские или внешние метрики для более точного и эффективного масштабирования.
  • Отслеживайте, тестируйте, итерируйте: Настройка HPA — это не разовая настройка. Поведение приложения, шаблоны трафика и базовая инфраструктура могут меняться. Регулярно пересматривайте производительность HPA и корректируйте настройки по мере необходимости.
  • Понимайте характеристики масштабирования вашего приложения: Масштабируется ли оно линейно с запросами? Имеет ли оно длительное время запуска? Является ли оно сохраняющим состояние? Эти характеристики влияют на вашу стратегию HPA.

Заключение

Относитесь к настройке HPA как к циклу обратной связи. Начните с точных запросов ресурсов, установите реалистичные minReplicas и maxReplicas, выберите метрику, которая отслеживает реальный спрос, и проверьте поведение при увеличении и уменьшении масштаба с помощью нагрузочных тестов, прежде чем производственный трафик будет зависеть от него.