Масштабирование по метрикам

Масштабирование по метрикам — это процесс автоматического или ручного изменения ресурсов (например, количества реплик подов, выделенных CPU/памяти) на основе определённых метрик. Метрики могут быть как по использованию CPU или памяти, так и по количеству запросов в секунду или размер очереди сообщений.

Масштабирование может выполняться на основе как базовых, так и произвольных метрик мониторинга. Например, масштабирование может осуществляться по следующим метрикам:

  • CPU (пода) — текущее использование процессора.
  • Память (пода) — текущее использование оперативной памяти.
  • RPS (Ingress) — количество запросов в секунду за 1, 5, 15 минут (rps_1m, rps_5m, rps_15m).
  • Среднее потребление CPU (пода) — за 1, 5, 15 минут (cpu_1m, cpu_5m, cpu_15m).
  • Среднее потребление памяти (пода) — за 1, 5, 15 минут (memory_1m, memory_5m, memory_15m).

Настройка

Для упрощения настройки масштабирования по метрикам, DKP предлагает использовать специальные ресурсы (Cluster*Metric и *Metric). Также, можно настроить масштабирование по собственным правилам расчета метрик.

Для настройки масштабирования по метрикам, выполняйте следующие действия:

  1. Включите модуль prometheus-metrics-adapter. Он позволяет создавать кастомные ресурсы, описывающие правила расчета метрики для масштабирования в виде PromQL-запроса.

    Включить модуль prometheus-metrics-adapter можно в веб-интерфейсе Deckhouse, или с помощью следующей команды:

    d8 platform module enable prometheus-metrics-adapter
    
  2. Определите PromQL-запрос, который будет описывать нужную метрику (например, скорость запросов к приложению или загрузку CPU за определённое время). Этот запрос регистрируется в кластере как метрика для HPA.
  3. Создайте ресурс HorizontalPodAutoscaler, указав в нём имя метрики и пороговое значение. Kubernetes будет опрашивать результат вашего PromQL-запроса и сравнивать с заданным порогом, добавляя или убавляя реплики (читайте в документации подробнее про настройку горизонтального масштабирования).

Пример запроса PromQL:

query: sum(rate(ingress_nginx_detail_requests_total{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>) OR on() vector(0)

В данном примере:

  • ingress_nginx_detail_requests_total — базовая метрика (счётчик запросов, например от контроллера Ingress NGINX);
  • rate(...[2m]) — вычисляет скорость увеличения счётчика за последние 2 минуты (requests per second);
  • sum(...) by (<<.GroupBy>>) — суммирует результат по некоторому набору меток (например, по имени Ingress, пространству имён и т. д.);
  • OR on() vector(0) — значение для PromQL, позволяющий вернуть «0», когда нет данных (иначе результат мог бы быть пустым и не учитываться).

Таким образом, этот PromQL-запрос даёт «число текущих запросов в секунду» по указанным меткам (Ingress, namespace и т. д.).

Когда у администратора есть метрика, описанная через PromQL-запрос (например, в объекте IngressMetric или аналогичном механизме), её можно указать в HorizontalPodAutoscaler (HPA) например так:

apiVersion: deckhouse.io/v1beta1
kind: IngressMetric
metadata:
  name: mymetric
  namespace: mynamespace
spec:
  query: sum(rate(ingress_nginx_detail_requests_total{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>) OR on() vector(0)
---
kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2
metadata:
  name: myhpa
  namespace: mynamespace
spec:
  # Указывается контроллер, который нужно масштабировать (ссылка на deployment или statefulset).
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 1
  maxReplicas: 2
  # Метрики, используемые для масштабирования.
  # Пример использования метрик.
  metrics:
  - type: Object
    object:
      # Объект, который обладает метриками в Prometheus.
      describedObject:
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        name: myingress
      metric:
        # Метрика, зарегистрированная с помощью custom resource IngressMetric или ClusterIngressMetric.
        # Можно использовать rps_1m, rps_5m или rps_15m которые поставляются с модулем prometheus-metrics-adapter.
        name: mymetric
      target:
        # Для метрик типа Object можно использовать `Value` или `AverageValue`.
        type: AverageValue
        # Масштабирование происходит, если среднее значение метрики для всех подов в Deployment сильно отличается от 10.
        averageValue: 10

При превышении (или падении ниже) заданного порога averageValue: 10 система изменит число реплик myapp в диапазоне от 1 до 2

Настройка метрик через CustomPrometheusRules

Если необходимо настроить собственные правила расчета метрик, без предлагаемых DKP ресурсов Cluster*Metric и *Metric, можно воспользоваться ресурсом CustomPrometheusRules.

Пример:

apiVersion: deckhouse.io/v1
kind: CustomPrometheusRules
metadata:
  # Рекомендованный шаблон для названия ваших CustomPrometheusRules.
  name: prometheus-metrics-adapter-mymetric
spec:
  groups:
  # Рекомендованный шаблон.
  - name: prometheus-metrics-adapter.mymetric
    rules:
    # Название вашей новой метрики.
    # Важно! Префикс 'kube_adapter_metric_' обязателен.
    - record: kube_adapter_metric_mymetric
      # Запрос, результаты которого попадут в итоговую метрику, нет смысла тащить в нее лишние лейблы.
      expr: sum(ingress_nginx_detail_sent_bytes_sum) by (namespace,ingress)

Все метрики с префиксом kube_adapter_metric_ автоматически регистрируются в Kubernetes API без необходимости создания CustomPrometheusRules. Это позволяет использовать уже существующие Prometheus-метрики для масштабирования без дополнительных конфигураций.

Работа с нестабильными метриками

При работе с нестабильными метриками (например, если метрика колеблется и вызывает избыточное масштабирование) рекомендуется:

  • Использовать агрегирующие функции PromQL. Например, avg_over_time() усредняет значение метрики за заданный промежуток времени, что помогает избежать резких скачков:

    apiVersion: deckhouse.io/v1beta1
    kind: ServiceMetric
    metadata:
      name: rmq-queue-forum-messages
      namespace: mynamespace
    spec:
      query: sum (avg_over_time(rabbitmq_queue_messages{<<.LabelMatchers>>,queue=~"send_forum_message",vhost="/"}[5m])) by (<<.GroupBy>>)
    
  • Настроить стабилизацию в поведении автоскейлера. Время стабилизации масштабирования можно увеличить, чтобы решения о добавлении или удалении реплик принимались на основе более устойчивых данных.

Получение значений метрик

Для получения списка метрик используйте команду:

d8 k get --raw /apis/custom.metrics.k8s.io/v1beta1/

Для получения значений метрик, привязанных к объектам используйте команду:

d8 k get --raw /apis/custom.metrics.k8s.io/v1beta1/namespaces/my-namespace/services/*/my-service-metric

Для получения значений метрик, созданных через NamespaceMetric используйте команду:

d8 k get --raw /apis/custom.metrics.k8s.io/v1beta1/namespaces/my-namespace/metrics/my-ns-metric

Для получения внешних метрик используйте команду:

d8 k get --raw /apis/external.metrics.k8s.io/v1beta1

Настройка автомасштабирования в веб-интерфейсе Deckhouse

В Deckhouse Kubernetes Platform можно настраивать параметры автомасштабирования узлов через веб-интерфейс Deckhouse. Это позволяет динамически изменять количество узлов в зависимости от нагрузки.

Чтобы настроить автомасштабирование в веб-интерфейсе:

  • Откройте веб-интерфейс Deckhouse;
  • В левом меню перейдите в раздел «Узлы» → «Группы узлов»;
  • Выберите нужную группу узлов;
  • В разделе «Параметры автомасштабирования» отобразятся текущие настройки.

В веб-интерфейсе Deckhouse доступны следующие настройки:

  • Параметр «Узлов на зону» – задаёт минимальное и максимальное количество узлов, которые могут быть запущены в одной зоне.
  • Параметр «Необходимо» – текущее количество узлов, необходимых для работы.
  • Параметр «Заказано» – текущее количество узлов, запланированное для запуска.
  • Параметр «Резерв» – дополнительный запас узлов.

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

  • Нажмите на значок редактирования рядом с параметром «Узлов на зону».
  • В появившемся окне укажите минимальное и максимальное количество узлов.
  • Нажмите «Применить», чтобы сохранить изменения, или «Отменить», чтобы сбросить редактирование.

При нажатии «Создать на основании» в веб-интерфейсе открывается форма настройки параметров автомасштабирования:

  1. Основные параметры:
    • Зоны – выбор зон, в которых будут создаваться машины. Позволяет распределять узлы между разными зонами доступности. Значение по умолчанию зависит от выбранного облачного провайдера и обычно соответствует всем зонам используемого региона
    • Приоритет масштабирования – используется, если в кластере есть несколько групп узлов с одинаковым приоритетом. Если приоритет не указан, то система случайным образом выбирает группу для добавления новых узлов.
    • Количество одновременно создаваемых машин при масштабировании вверх – определяет, сколько машин может быть добавлено одновременно при масштабировании вверх. Например, если значение 1, то узлы добавляются по одному.
    • Недоступное количество инстансов при RollingUpdate – количество узлов, которые могут быть недоступны во время обновления (RollingUpdate). Значение 0 означает, что обновление будет проходить поочерёдно, без временного снижения числа работающих узлов.
  2. Резервные узлы и ресурсы:
    • Число резервных узлов от общего количества узлов – можно указать конкретное число узлов (например, 2-6) или процент от общего числа узлов (например, 15%). Резервный узел — это узел кластера, на котором резервируются ресурсы, доступные в любой момент для масштабирования. Наличие такого узла позволяет автоскейлеру кластера не ждать инициализации узла, а сразу размещать на нем нагрузку. Это позволяет ускорить масштабирование вверх на несколько минут.
    • Ресурсы, занимаемые на резервных узлах, % – процент ресурсов, который выделяется на резервных узлах. Допустимые значения: от 1% до 80%. Например, если указать 50%, то половина ресурсов узла будет зарезервирована.
  3. Дополнительные параметры:
    • Quick Shutdown (Быстрое выключение) – включает ускоренное отключение узлов, снижая время ожидания drain’а до 5 минут.