Немного практики для «пощупать» HPA в кластере, поиграться параметрами масштабирования. Можно было бы быстро перейти от теории к практике, ну или наоборот. В примерах используется масштабирование на основе очереди RabbitMQ. Можно использовать minikube, MicroK8s, или где вам удобно… Для удобства развёртывания примеры k8s-hpa-rabbitmq-demo.
В данном случае тестировать HPA можно тремя способами: с помощью одной KEDA, с помощью Prometheus Adapter и метрик из Prometheus, а также с помощью KEDA и метрик из VictoriaMetrics. Необходимо выбрать один или использовать по очереди. Все способы разворачиваются с минимальными требованиями без «лишних» объектов. Для работы с очередью понадобится агент mrlioncub/rabbitmq-agent в кластере.
Перед разворачиванием подключим репозитории helm:
helm repo add helmforge https://repo.helmforge.devhelm repo add prometheus-community https://prometheus-community.github.io/helm-chartshelm repo add vm https://victoriametrics.github.io/helm-chartshelm repo add kedacore https://kedacore.github.io/chartshelm repo add k8s-hpa-rabbitmq-demo https://mrlioncub.github.io/k8s-hpa-rabbitmq-demohelm repo update
Для всех тестов нам понадобится RabbitMQ с включённым /metrics:
charts/rabbitmq/values.yaml:
#это имя сервиса понадобится для обращения fullnameOverride: "rabbitmq-server"auth: username: guest password: guestpodAnnotations: prometheus.io/scrape: "true"metrics: enabled: truesingleNode: persistence: enabled: false
helm upgrade --create-namespace --namespace k8-hpa-rabbitmq-demo --install rabbitmq-server helmforge/rabbitmq -f charts/rabbitmq/values.yaml
Полезные команды, которые могут понадобиться для анализа:
kubectl -n k8-hpa-rabbitmq-demo exec rabbitmq-server-0 -- rabbitmqctl list_queues -s — показать значение очереди
kubectl -n k8-hpa-rabbitmq-demo run curl -it --rm --image=alpine/curl --restart=Never -- curl -s http://rabbitmq-server:15692/metrics | grep 'rabbitmq_queue_messages{vhost="/",queue="task_queue"}' — показать очередь уже в самих метриках сервиса
Способ 1: KEDA
Для этого способа нужна сама KEDA:
helm upgrade --create-namespace --namespace k8-hpa-rabbitmq-demo --install keda kedacore/keda
и тот кто будет обрабатывать очередь:
helm upgrade --create-namespace --namespace k8-hpa-rabbitmq-demo --install rabbitmq-agent-reciever k8s-hpa-rabbitmq-demo/rabbitmq-agent --set keda.enabled=true
Проверим работу ScaledObject для работы с KEDA, созданного при развёртывании rabbitmq-agent-reciever. Пример, что работает (READY: True):
$ kubectl get scaledobject -n k8-hpa-rabbitmq-demoNAME SCALETARGETKIND SCALETARGETNAME MIN MAX READY ACTIVE FALLBACK PAUSED TRIGGERS AUTHENTICATIONS AGErabbitmq-scaledobject apps/v1.Deployment rabbitmq-agent-reciever 1 10 True False False False rabbitmq 2m
Способ 2: Prometheus и Prometheus Adapter
Соответственно понадобятся Prometheus и Prometheus Adapter
charts/prometheus/values.yaml (подробнее):
alertmanager: enabled: falseprometheus-pushgateway: enabled: falseprometheus-node-exporter: enabled: falsekube-state-metrics: enabled: false
charts/prometheus-adapter/values.yaml (подробнее):
prometheus: url: http://prometheus-server port: 80rules: default: false custom: - seriesQuery: 'rabbitmq_queue_messages{namespace!="",pod!="",queue="task_queue"}' resources: overrides: namespace: {resource: "namespace"} pod: {resource: "pod"} metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>,queue="task_queue"}) by (<<.GroupBy>>)
helm upgrade --create-namespace --namespace k8-hpa-rabbitmq-demo --install prometheus prometheus-community/prometheus -f charts/prometheus/values.yamlhelm upgrade --create-namespace --namespace k8-hpa-rabbitmq-demo --install prometheus-adapter prometheus-community/prometheus-adapter -f charts/prometheus-adapter/values.yaml
и кто будет обрабатывать очередь:
helm upgrade --create-namespace --namespace k8-hpa-rabbitmq-demo --install rabbitmq-agent-reciever k8s-hpa-rabbitmq-demo/rabbitmq-agent --set autoscaling.enabled=true
Проверим, что всё появилось в CustomMetrics, которые создал Prometheus Adapter из Prometheus. Пример, что работает:
$ kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1/namespaces/k8-hpa-rabbitmq-demo/pods/rabbitmq-server-0/rabbitmq_queue_messages | jq .{ "kind": "MetricValueList", "apiVersion": "custom.metrics.k8s.io/v1beta1", "metadata": {}, "items": [ { "describedObject": { "kind": "Pod", "namespace": "k8-hpa-rabbitmq-demo", "name": "rabbitmq-server-0", "apiVersion": "/v1" }, "metricName": "rabbitmq_queue_messages", "timestamp": "2026-06-09T08:02:47Z", "value": "0", "selector": null } ]}
Способ 3: VictoriaMetrics и KEDA
charts/victoriametrics/values.yaml (подробнее):
server: scrape: enabled: true config: scrape_configs: - job_name: rabbitmq static_configs: - targets: - rabbitmq-server:15692 persistentVolume: enabled: false
helm upgrade --create-namespace --namespace k8-hpa-rabbitmq-demo --install victoriametrics vm/victoria-metrics-single -f charts/victoriametrics/values.yamlhelm upgrade --create-namespace --namespace k8-hpa-rabbitmq-demo --install keda kedacore/keda
Проверим работу ScaledObject можно аналогично как и в первом способе.
Очередь и HPA
Проверить HPA на любом из способов:
kubectl -n k8-hpa-rabbitmq-demo get hpa
Пример работающего HPA, в первом и третьем способе:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEkeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 0/30 (avg) 1 10 1 40s
Пример работающего HPA, во втором способе:
$ kubectl -n k8-hpa-rabbitmq-demo get hpaNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGErabbitmq-server-hpa Deployment/rabbitmq-agent-reciever 0/30 1 10 1 4m47s
При TARGETS: <unknown>/30 значит объект hpa создан, но данные с метрик ещё не поступили.
После уже можно пробовать заполнить очередь и смотреть как работает HPA.
Отправить 50 сообщений в очередь и проверим как меняется hpa:
kubectl --namespace k8-hpa-rabbitmq-demo run sender -it --rm --image=mrlioncub/rabbitmq-agent --restart=Never -- sender 50kubectl -n k8-hpa-rabbitmq-demo get hpa -w
Как работает HPA для первого и третьего способов:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEkeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever <unknown>/30 (avg) 1 10 0 0skeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 0/30 (avg) 1 10 1 15skeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 48/30 (avg) 1 10 1 60skeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 23/30 (avg) 1 10 2 76skeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 21500m/30 (avg) 1 10 2 91skeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 18500m/30 (avg) 1 10 2 106skeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 16/30 (avg) 1 10 2 2m1skeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 12500m/30 (avg) 1 10 2 2m16skeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 8/30 (avg) 1 10 2 2m31skeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 5/30 (avg) 1 10 2 2m46skeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 2/30 (avg) 1 10 2 3m1skeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 0/30 (avg) 1 10 2 3m16skeda-hpa-rabbitmq-scaledobject Deployment/rabbitmq-agent-reciever 0/30 (avg) 1 10 1 7m16s
Как работает HPA для второго способа:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGErabbitmq-server-hpa Deployment/rabbitmq-agent-reciever <unknown>/30 1 10 0 4srabbitmq-server-hpa Deployment/rabbitmq-agent-reciever <unknown>/30 1 10 1 15srabbitmq-server-hpa Deployment/rabbitmq-agent-reciever 0/30 1 10 1 60srabbitmq-server-hpa Deployment/rabbitmq-agent-reciever 41/30 1 10 1 2mrabbitmq-server-hpa Deployment/rabbitmq-agent-reciever 41/30 1 10 2 2m15srabbitmq-server-hpa Deployment/rabbitmq-agent-reciever 41/30 1 10 3 2m30srabbitmq-server-hpa Deployment/rabbitmq-agent-reciever 41/30 1 10 5 2m45srabbitmq-server-hpa Deployment/rabbitmq-agent-reciever 5/30 1 10 7 3mrabbitmq-server-hpa Deployment/rabbitmq-agent-reciever 0/30 1 10 7 4m1srabbitmq-server-hpa Deployment/rabbitmq-agent-reciever 0/30 1 10 2 8m1srabbitmq-server-hpa Deployment/rabbitmq-agent-reciever 0/30 1 10 1 9m1s
Какая разница
Разберём разницу в вариантах, в одном TARGETS с (avg) в другом REPLICAS поднималась до 7. В ScaledObject тип метрики по умолчанию AverageValue (1,2), а для второго варианта в hpa.yaml у нас указан тип Value.
AverageValue рассчитывается как среднее кол-во сообщений на каждую реплику (т.е. делится на количество подов), а Value — абсолютное значение. У нас 50 сообщений при пороге в 30 (hpa.yaml, keda.yaml, kedavm.yaml): 50/30 = 1.67, что превышает 10% по умолчанию для того, чтобы kubernetes начал масштабирование.
Поиграться не только с вариантами, но и с rabbitmq-agent-reciever настройками для hpa в yaml, скачав репозиторий:
git clone --depth 1 https://github.com/mrlioncub/k8s-hpa-rabbitmq-demo.gitcd k8s-hpa-rabbitmq-demo
Установить helm из директории, если изменился helm (например, для KEDA):
helm upgrade --create-namespace --namespace k8-hpa-rabbitmq-demo --install rabbitmq-agent-reciever charts/rabbitmq-agent --set keda.enabled=true
ссылка на оригинал статьи https://habr.com/ru/articles/1046331/