Autoscaler Kubernets - Не удается получить loadbalancing.googleapis.com | https | request_count - PullRequest
1 голос
/ 22 октября 2019

Я пытаюсь определить Горизонтальный Автоскалер для двух сервисов Kubernetes.

Стратегия Autoscaler использует 3 метрики:

  1. процессор
  2. pubsub. googleapis.com | subscription | num_undelivered_messages
  3. loadbalancing.googleapis.com | https | request_count

CPU и num_undelivered_messages получены правильно,но независимо от того, что я делаю, я не могу получить метрику request_count .

Первая служба - это внутренняя служба (служба A), а другая (служба B) - это API, который используетВход для управления внешним доступом к службе.

Стратегия автоматического масштабирования основана на документации Google: Автоматическое масштабирование развертываний с использованием внешних метрик .

Для службы A следующиеопределяет метрики, используемые для автоматического масштабирования:

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: ServiceA
spec:
  scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: ServiceA
  minReplicas: 1
  maxReplicas: 3
  metrics:
  - type: Resource
    resource:
      name: cpu
      targetAverageUtilization: 80
  - external:
      metricName: pubsub.googleapis.com|subscription|num_undelivered_messages
      metricSelector:
        matchLabels:
          resource.labels.subscription_id: subscription_id
      targetAverageValue: 100
    type: External

Для службы B следующие параметры определяют для автоматического масштабирования:

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: ServiceB
spec:
  scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: ServiceB
  minReplicas: 1
  maxReplicas: 3
  metrics:
  - type: Resource
    resource:
      name: cpu
      targetAverageUtilization: 80
  - external:
      metricName: loadbalancing.googleapis.com|https|request_count
      metricSelector:
        matchLabels:
          resource.labels.forwarding_rule_name: k8s-fws-default-serviceb--3a908157de956ba7
      targetAverageValue: 100
    type: External      

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

$ kubectl get apiservices |egrep metrics
v1beta1.custom.metrics.k8s.io          custom-metrics/custom-metrics-stackdriver-adapter   True        2h
v1beta1.external.metrics.k8s.io        custom-metrics/custom-metrics-stackdriver-adapter   True        2h
v1beta1.metrics.k8s.io                 kube-system/metrics-server                          True        2h
v1beta2.custom.metrics.k8s.io          custom-metrics/custom-metrics-stackdriver-adapter   True        2h

Для службы A все метрики, CPU и num_undelivered_messages, правильно получены:

$ kubectl get hpa ServiceA
NAME       REFERENCE             TARGETS               MINPODS   MAXPODS   REPLICAS   AGE
ServiceA   Deployment/ServiceA   0/100 (avg), 1%/80%   1         3         1          127m

Для службы B,HPA не может получить количество запросов:

$ kubectl get hpa ServiceB
NAME                REFERENCE    TARGETS                              MINPODS   MAXPODS   REPLICAS   AGE
ServiceB   Deployment/ServiceB   <unknown>/100 (avg), <unknown>/80%   1         3         1          129m

При доступе к входному сообщению появляется следующее предупреждение:

невозможно получить внешнюю метрику по умолчанию / loadbalancing.googleapis.com | https |request_count / & LabelSelector {MatchLabels: map [string] string {resource.labels.forwarding_rule_name: k8s-fws-default-serviceb - 3a908157de956ba7,}, MatchExpressions: [],}: метрики не возвращаются из внешних метрик API

Правило metricSelector для правила пересылки является правильным, что подтверждается при описании входа (показана только соответствующая информация):

$ kubectl describe ingress serviceb
Annotations:
  ingress.kubernetes.io/https-forwarding-rule:  k8s-fws-default-serviceb--3a908157de956ba7

Я пытался использоватьдругой селектор метрик, например, использование url_map_name , но безрезультатно, у меня похожая ошибка.

Я следовал точным рекомендациям в Google Documeи проверил с несколькими онлайн-учебниками, которые ссылаются на тот же процесс, но я не смог понять, что мне не хватает. Возможно, мне не хватает какой-то конфигурации или каких-то конкретных деталей, но я нигде не могу найти ее в документации.

Чего мне не хватает, это объясняет, почему я не могу получить loadbalancing.googleapis.com | https | request_count метрика?

Ответы [ 3 ]

1 голос
/ 22 октября 2019

Большое спасибо за подробный ответ.

При использовании metricSelector для выбора конкретного forwarding_rule_name нам необходимо использовать точное forwarding_rule_name , как определеновход:

metricSelector:
    matchLabels:
    resource.labels.forwarding_rule_name: k8s-fws-default-serviceb--3a908157de956ba7
$ kubectl describe ingress

Name: serviceb
...

Annotations:
  ingress.kubernetes.io/https-forwarding-rule:  k8s-fws-default-serviceb--9bfb478c0886702d
  ...
  kubernetes.io/ingress.allow-http:             false
  kubernetes.io/ingress.global-static-ip-name:  static-ip

Проблема заключается в том, что суффикс forwarding_rule_name (3a908157de956ba7) изменяется для каждого развертывания и создается динамически при создании входа:

  • k8s-fws-default-serviceb - 3a908157de956ba7

У нас полностью автоматизированное развертывание с использованием Helm и, как таковое, при создании HPA, мы не знаем, каким будет forwarding_rule_name .

И, похоже, matchLabels не принимает регулярные выражения, иначе мы бы просто что-то сделалинапример:

metricSelector:
    matchLabels:
    resource.labels.forwarding_rule_name: k8s-fws-default-serviceb--*

Я пробовал несколько подходов, но все безуспешно:

  1. Использование аннотаций для принудительного forwarding_rule_name
  2. Использованиедругая мамаchLabel, as backend_target_name
  3. Получите forwarding_rule_name с помощью команды, чтобы я мог вставить его позже в файл yaml.

Использование аннотаций для принудительного использования forwarding_rule_name :

При создании входа я могу использовать конкретные аннотации, чтобы изменить поведение по умолчанию, или определить конкретные значения, например, для входа.yaml:

  annotations:
    kubernetes.io/ingress.global-static-ip-name: static-ip

Я пытался использовать аннотацию правила переадресации https для принудительного задания определенного «статического» имени, но это не сработало:

  annotations:
    ingress.kubernetes.io/https-forwarding-rule: some_name


  annotations:
    kubernetes.io/https-forwarding-rule: some_name

Используйте другой machLabel, например backend_target_name

metricSelector:
        matchLabels:
          resource.labels.backend_target_name: serviceb

Также не удалось.

Получите forwarding_rule_name с помощью команды

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

gcloud compute forwarding-rules list
NAME                                        P_ADDRESS   IP_PROTOCOL  TARGET
k8s-fws-default-serviceb--4e1c268b39df8462  xx          TCP          k8s-tps-default-serviceb--4e1c268b39df8462
k8s-fws-default-serviceb--9bfb478c0886702d  xx          TCP          k8s-tps-default-serviceb--9bfb478c0886702d

Есть ли способ, позволяющий мне выбрать нужный мне ресурс, чтобы получитьКоличество запросов метрики?

1 голос
/ 22 октября 2019

Кажется, что определяемая вами метрика недоступна в External Metrics API . Чтобы выяснить, что происходит, вы можете напрямую проверить API внешних метрик:

kubectl get --raw="/apis/external.metrics.k8s.io/v1beta1" | jq

Показана ли в выходных данных метрика loadbalancing.googleapis.com | https | request_count ?

Затем вы можете копать глубже, отправляя запросы следующей формы :

kubectl get --raw="/apis/external.metrics.k8s.io/v1beta1/namespaces/<namespace_name>/<metric_name>?labelSelector=<selector>" | jq

И посмотрите, что возвращается, учитывая ваше имя метрики и определенный селектор метрики.

Это именно те запросы, которые Горизонтальный стручковый автомаслер также делает во время выполнения. Реплицируя их вручную, вы сможете точно определить источник проблемы.


Комментарии к дополнительной информации:

1) 83m - это способ записи Kubernetes 0,083 (читается как 83 «милли-единицы»).

2) В вашем определении HorizontalPodAutoscaler вы используете targetAverageValue. Таким образом, если существует несколько целей с этим показателем, HPA рассчитывает их среднее значение. Таким образом, 83 м могут быть в среднем из нескольких целей. Чтобы убедиться, что вы используете только метрику одной цели, вы можете использовать поле targetValue (см. Справочник по API ).

3) Не уверен, почему массив items: [] в ответе API пуст. В документации упоминается, что после выборки данные не отображаются в течение 210 секунд ... Вы можете попробовать выполнить запрос API, когда HPA не запущен.

0 голосов
/ 22 октября 2019

Кажется, все было в порядке с моим кодом, но есть задержка (приблизительно 10 м), прежде чем доступна метрика request_count . По истечении этого периода метрика теперь вычисляется и доступна:

$ kubectl get hpa ServiceB
NAME                REFERENCE    TARGETS                MINPODS   MAXPODS   REPLICAS   AGE
ServiceB   Deployment/ServiceB   83m/100 (avg), 1%/80%  1         3         1          18m

Теперь, что касается loadbalancing.googleapis.com | https | request_count метрика, я не понимаю, как это происходитпредставил. Что означает 83m ?

Согласно документации Google для Метрики балансировки нагрузки :

https / request_bytes_count Байт запроса

DELTA, INT64, By

GA

Количество запросов, обслуживаемых балансировщиком нагрузки HTTP / S. Отбор проб каждые 60 секунд. После выборки данные не отображаются в течение до 210 секунд.

Согласно Сведения о метрике :

В метрике DELTA каждая точка данныхпредставляет изменение значения за интервал времени. Например, число запросов на обслуживание, полученных с момента предыдущего измерения, будет дельта-метрикой.

Я сделал один единственный запрос к службе, поэтому я ожидал значение 1, и я не могу понять, что означает 83m .

Другая возможность, может быть, что я не использую правильную метрику. Я выбрал показатель loadbalancing.googleapis.com | https | request_count , предполагая, что он предоставит число запросов, которые были выполнены службой через балансировщик нагрузки.

Разве это не та информация, которую предоставляет метрика loadbalancing.googleapis.com | https | request_count ?

Относительно приведенного выше комментария при выполнении:

kubectl get --raw="/apis/external.metrics.k8s.io/v1beta1/namespaces/default/pubsub.googleapis.com|subscription|num_undelivered_messages" | jq

я получаю правильные данные:

... {"metricName": "pubsub.googleapis.com | subscription | num_undelivered_messages", "metricLabels": {"resource.labels. ID_проекта:: "id-проекта", "resource.labels.subscription_id": "subscription_id", "resource.type": "pubsub_subscription"}, "отметка времени": "2019-10-22T15: 39: 58Z", "значение":" 4 "} ...

но при выполнении:

kubectl get --raw="/apis/external.metrics.k8s.io/v1beta1/namespaces/default/loadbalancing.googleapis.com|https|request_count" | jq

я ничего не получаю обратно:

{" kind ": "ExternalMetricValueList", "apiVersion": "external.metrics.k8s.io/v1beta1", "metadata": {"selfLink":> "/ apis / external.metrics.k8s.io / v1beta1 / namespaces / default / loadbalancing.googleapis.com% 7Chttps% 7Crequest_count "}," items ": []}

...