Вступление
Сегодня мы поговорим о том как можно скейлить поды в Kubernetes при помощи внешних метрик на примере воркеров RabbitMQ А так-же я расскажу о том с какими сложностями и подводными камнями можно столкнутся настраивая такую сборку Так-как я свою очередь столкнувшись с этой проблемой не нашел рабочего и понятного мануала, решил что для себя задокументировать эту
Условия задачи
Предположим к нам пришел заказчик(разработчик, лид или егерь из лесу) и попросил сделать чтоб поды в кластере скейлились в зависимости от того сколько накопилось в очереди сообщений
Как говорил Доктор Дью: Время начинать
Прежде всего нам нужно чтоб в кластере был установлен Prometheus
Rabbitmq Exporter
Для того чтоб стягивать метрики с ребита нам нужен экспортер. К сожалению встроенный экспортер ребита не вытягивает нужные нам данные, а конкретно количество сообщений разбито по очередям, вхостам, и всему прочему.
Потому берём экспортер он многоуважаемого kbudde, он соберает метрики из GUI ребита, потому в самом ребите никаких плагинов ставить не нужно.
Если морда ребита с SSL сертификатом то нужно будет закинуть сертификаты в контейнер мониторинга, или-же выключить проверку SKIPVERIFY
Деплоем чарт с екпортером
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm upgrade \
--atomic \
--wait \
--namespace test-namespace \
--install rabbitmq-exporter \
prometheus-community/prometheus-rabbitmq-exporter \
\
--set fullnameOverride=rabbitmq-exporter \
\
--set prometheus.monitor.enabled=true \
\
--set rabbitmq.url=https://RABBITMQ_MANAGEMENT_HOST:RABBITMQ_MANAGEMENT_PORT \
--set rabbitmq.user=guest \
--set rabbitmq.password=guest \
--set rabbitmq.skip_verify=true \
--set loglevel=debug
Дальше проверяем собираются ли метрики самим экспортером
kubectl --namespace test-namespace port-forward deployment/rabbitmq-exporter 9419:9419
curl -v http://localhost:9419/metrics | grep rabbitmq_up
Если в выхлопе курла мы видим rabbitmq_up 1 значит экспортер собирает метрики.
Проверяем метрики в Prometheus
Заходим в веб морду Prometheus в Service Discovery и проверяем есть ли наш таргет.
serviceMonitor/test-namespace/rabbitmq-exporter/0 (1 / 5 active targets)
И проверяем на всякий случай есть ли сами данные в Graph rabbitmq_up
Настраиваем HorizontalPodAutoscaler
Далее нам нужно выбрать каким методом мы будем получать данные в наш hpa. Существует 3 апишки для получения метрик:
- metrics.k8s.io
- custom.metrics.k8s.io
- external.metrics.k8s.io
В нашем случае мы будем использовать custom метрики. Потому проверяем наличие в апи данных по этим метрикам
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 | jq .
Если данные возвращаются значит у вас стоит адаптер и можно продолжать дальше. Далее добавляем в чарт HPA
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name:
spec:
groups:
- name: -queue-size # Define the name of your rule
rules:
- record: _messages_waiting_in_queue # Уникальное имя метрики.
expr: rabbitmq_queue_messages{queue="", vhost=""} # Запрос в Prometheus c фильтрацией
---
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name:
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name:
minReplicas:
maxReplicas:
metrics:
- type: Object
object:
metric:
name: _messages_waiting_in_queue
describedObject:
apiVersion: v1
kind: Namespace
name:
target:
type: Value
value:
Важные моменты
- метрика
_messages_waiting_in_queueдолжна быть уникальна, чтоб система не конфликтовала если в неймспейсе есть другие hpa - Запрос к Prometheus должен отдавать одну запись. В случае когда запрос отдает несколько значений могут быть непредвиденное поведение Полезные статьи по этой теме:
- https://stackoverflow.com/questions/66423005/hpa-with-different-namespaces
- https://itnext.io/horizontal-pod-autoscaling-with-custom-metric-from-different-namespace-f19f8446143b