Как заставить HPA масштабировать развертывание на основе показателей, созданных другим развертыванием

#kubernetes #horizontal-scaling

#kubernetes #горизонтальное масштабирование

Вопрос:

Чего я пытаюсь достичь, так это создания горизонтального модуля автоматического масштабирования, способного масштабировать worker модули в соответствии с пользовательской метрикой, созданной controller модулем.

У меня уже есть Prometheus scraping, Prometheus Adapater, сервер пользовательских показателей, полностью работоспособный, и масштабирование worker развертывания с помощью пользовательских показателей, my_controller_metric созданных worker модулями, уже работает.

Теперь мои worker модули больше не выдают эту метрику, но controller это делает. Похоже, что автоматическое масштабирование API / v1 не поддерживает эту функцию. Однако при необходимости я могу указать HPA с помощью API autoscaling / v2beta1.

Вот моя спецификация для этого HPA:

 apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: my-worker-hpa
  namespace: work
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: my-worker-deployment
  metrics:
  - type: Object
    object:
      target:
        kind: Deployment
        name: my-controller-deployment
      metricName: my_controller_metric
      targetValue: 1
  

Когда конфигурация применяется с kubectl apply -f my-worker-hpa.yml , я получаю сообщение:

 horizontalpodautoscaler "my-worker-hpa" configured
  

Хотя это сообщение кажется нормальным, HPA не работает. Является ли эта спецификация неправильной?

Как я уже сказал, показатель доступен на сервере пользовательских показателей с kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq . | grep my_controller_metric .

Это сообщение об ошибке от HPA:

 Type           Status  Reason                 Message
----           ------  ------                 -------
AbleToScale    True    SucceededGetScale      the HPA controller was able to get the target's current scale
ScalingActive  False   FailedGetObjectMetric  the HPA was unable to compute the replica count: unable to get metric my_controller_metric: Deployment on work my-controller-deployment/unable to fetch metrics from custom metrics API: the server could not find the metric my_controller_metric for deployments
  

Спасибо!

Ответ №1:

В вашем случае проблема заключается в конфигурации HPA: spec.metrics.object.target также следует указать версию API. Включение apiVersion: extensions/v1beta1 под spec.metrics.object.target должно исправить это.

Кроме того, остается открытым вопрос о лучшей проверке конфигурации в HPA: https://github.com/kubernetes/kubernetes/issues/60511

Ответ №2:

У меня был точно такой же пользовательский случай, когда у меня был worker модуль, который нужно было масштабировать на master pod. Я не мог разобраться в этой проблеме, поскольку type: Pods извлекал показатели из модуля, который он масштабировал, он же worker pod. И, черт возьми, я был рад наткнуться на этот вопрос только для того, чтобы обнаружить, что он открыт.

Тем не менее, это вдохновило меня на поиск решения.

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

Адаптер Prometheus:

 prometheus-adapter:
  rules:
    default: false
    custom:
      - seriesQuery: ' foobar'
        resources:
          overrides:
            pod:
              resource: pod
            namespace:
              resource: namespace
        name:
          matches: ^(.*)
          as: "metricName"
        metricsQuery: barfoo
  

HPA:

 apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: name-hpa
  labels:
      {{- include "raw-ds.labels" $global | nindent 4 }}
    app: {{ $deployName }}
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: {{ $deployName }}
  minReplicas: {{ $.Values.autoscaling.minReplicas }}
  maxReplicas: {{ $.Values.autoscaling.maxReplicas }}
  metrics:
    - type: Object
      object:
        describedObject:
          kind: Namespace
          name: default
          apiVersion: v1
        metric:
          name:  metricName
        target:
          type: Value
          value: 2k