Всем привет! Меня зовут Дмитрий Мамонтов, я DevOps-инженер с опытом работы более пяти лет, а также наставник на курсе «DevOps для эксплуатации и разработки» и один из авторов курса «Эксплуатация и разработка в Kubernetes» в Яндекс Практикуме.
Представим, что у нас есть приложение, которое шлёт свои метрики в Yandex Monitoring, и стоит задача: масштабировать это приложение с помощью HPA в кластере Kubernetes в зависимости от метрики.
Есть два популярных варианта решения этой задачи:
-
Настроить интеграцию с prometheus-adapter и перекладывать метрики в Prometheus из Yandex Monitoring. Для этого метода нам необходим установленный Prometheus и prometheus-adapter. Prometheus будет опрашивать Yandex Monitoring, а адаптер будет отдавать метрику для работы HPA .
-
Использовать Keda-operator. В данном случае опрашивать Yandex Monitoring будет Keda и сама управлять работой HPA. Воспользуемся этим вариантом.
Генерация тестовых метрик
Если приложения у нас нет под рукой, а попробовать хочется, то можно воспользоваться примером из документации или сгенерировать несколько значений метрик с помощью утилитыcurl
.
yc init yc iam create-token
-
Отправим несколько метрик запросом вида, подставив значение folder и токена:
curl -X POST \ 'https://monitoring.api.cloud.yandex.net/monitoring/v2/data/write?folderId=ВАШФОЛДЕР&service=custom' \ -H "Authorization: Bearer ВАШТОКЕН" \ -H "Content-Type: application/json" \ -d '{ "metrics": [ { "name": "trigger_metric", "labels": { "foo": "bar" }, "value": 1000 } ] }'
Ответ будет вида:
{"writtenMetricsCount":1}
На графике будут видны метрики:
Приступаем к настройке масштабирования
Установку k8s (в облаке или вне его) я пропущу. В Яндексе можно поднять как через веб-консоль (или yc
), так и с помощью terraform-провайдера.
Управлять масштабированием будем с помощью KEDA.
KEDA — это компонент для Kubernetes, который расширяет возможности горизонтального масштабирования (HPA). Он позволяет масштабировать приложения на основе событий или метрик от внешних источников, таких как очереди сообщений, базы данных, сервисы мониторинга и другие.
Для его настройки в нашем примере необходимо поставить оператор и настроить обращения в Yandex Monitoring.
Приступим:
Процесс установки оператора описан тут. Воспользуемся готовым helm-чартом.
# Добавим репозиторий чартов $ helm repo add kedacore https://kedacore.github.io/charts $ helm repo update # Установим оператора Keda: # При желании, можно поправить\посмотреть параметры установки в values $ helm show values kedacore/keda $ helm install keda kedacore/keda --namespace keda --create-namespace
Итого получим установленный оператор:
$ kubectl get po -n keda NAME READY STATUS RESTARTS AGE keda-admission-webhooks-85bfd658f5-55zhf 1/1 Running 0 4h16m keda-operator-c6f875576-465sm 1/1 Running 1 (4h16m ago) 4h16m keda-operator-metrics-apiserver-6d5b8869f-w6lz2 1/1 Running 0
Приступаем к интеграции с Yandex Monitoring.
Сначала установим тестовое приложение, которое будем масштабировать (если у вас его ещё нет).
apiVersion: apps/v1 kind: Deployment metadata: name: simple-app labels: app: nginx spec: replicas: 3 # изначально будет 3 пода selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest
Запустим его в неймспейсе по-умолчанию:
kubectl apply -f deploy.yaml
Метрику будем забирать по http в формате prometheus.
Для наших целей такой способ отлично подойдет так, как нам для принятия решения о масштабировании нужно именно последнее значение.
Чтобы обратиться к API за метрикой нам необходим будет статический API KEY. Для этого необходимо создать сервис-аккаунт с привилегией monitoring.viewer
и выписать ключ от его имени.
С помощью curl можно получить значение так (не забудьте подставить ключ и фолдер):
$ curl "https://monitoring.api.cloud.yandex.net/monitoring/v2/prometheusMetrics?folderId=ВАШФОЛДЕР&service=custom" \ -H "Authorization: Bearer ВАШ APIKEY" # TYPE trigger_metric gauge trigger_metric{foo="bar"} 1000.0
Далее нам нужно описать сущность ScaledObject, настроить скейлер Metric-api и поместить токен для доступа к метрикам в секрет.
Вообще, Keda имеет очень много скейлеров, которые позволяют интегрировать её с почти любой базой данных или системой мониторинга.
Обратите внимание, что версия API в альфе и может поменяться в новой версии контроллера.
apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: my-scaler spec: scaleTargetRef: name: simple-nginx pollingInterval: 5 # Как часто опрашивать. Default: 30 seconds cooldownPeriod: 10 # Сколько ждать после изменения. Default: 300 seconds minReplicaCount: 1 # Минимальное значение maxReplicaCount: 5 # Максимальное значение triggers: - type: metrics-api metadata: targetValue: "200.0" # После какого значения метрики начинаем увеличивать\уменьшать поды activationTargetValue: "50.0" # Можно установить значения для активации\деактивации ScaledObject format: "prometheus" url: "https://monitoring.api.cloud.yandex.net/monitoring/v2/prometheusMetrics?folderId=ВАШФОЛДЕР&service=custom" # урл, где искать метрику valueLocation: "trigger_metric{foo=\"bar\"}" # не забываем экранировать кавычки authMode: "bearer" authenticationRef: name: keda-metric-api-creds --- apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: keda-metric-api-creds spec: secretTargetRef: - parameter: token name: keda-metric-api-secret key: token --- apiVersion: v1 kind: Secret metadata: name: keda-metric-api-secret data: token: "ТОКЕН APIKEY ЗАШИФРОВАННЫЙ В BASE64"
Деплоим вышеописанные манифесты:
$ kubectl apply -f scale.yml
Проверяем:
$ kubectl get scaledobject NAME SCALETARGETKIND SCALETARGETNAME MIN MAX TRIGGERS AUTHENTICATION READY ACTIVE FALLBACK PAUSED AGE my-scaler apps/v1.Deployment simple-nginx 1 5 metrics-api keda-metric-api-creds True True False Unknown 51m $ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE keda-hpa-my-scaler Deployment/simple-nginx 200/200 (avg) 1 5 5 52m
Видим, что создав сущность scaledobject
контроллер создал еще и hpa
, который будет управлять масштабированием приложения.
Отправим метрику со значением 100 и убедимся, что кол-во подов уменьшилось.
$ curl -X POST \ 'https://monitoring.api.cloud.yandex.net/monitoring/v2/data/write?folderId=ВАШФОЛДЕР&service=custom' \ -H "Authorization: Bearer ВАШТОКЕН" \ -H "Content-Type: application/json" \ -d '{ "metrics": [ { "name": "trigger_metric", "labels": { "foo": "bar" }, "value": 100 } ] }' $ kubectl get po NAME READY STATUS RESTARTS AGE simple-nginx-7bf8c77b5b-qth7k 1/1 Running 0 4h
Отправим значение 1000 и проверим увеличение.
$ curl -X POST \ 'https://monitoring.api.cloud.yandex.net/monitoring/v2/data/write?folderId=ВАШФОЛДЕР&service=custom' \ -H "Authorization: Bearer ВАШТОКЕН" \ -H "Content-Type: application/json" \ -d '{ "metrics": [ { "name": "trigger_metric", "labels": { "foo": "bar" }, "value": 1000 } ] }' $ kubectl get po NAME READY STATUS RESTARTS AGE simple-nginx-7bf8c77b5b-gb2ft 1/1 Running 0 44s simple-nginx-7bf8c77b5b-j5df4 1/1 Running 0 44s simple-nginx-7bf8c77b5b-jgfd8 1/1 Running 0 44s simple-nginx-7bf8c77b5b-nhmwb 1/1 Running 0 29s simple-nginx-7bf8c77b5b-qth7k 1/1 Running 0 4h1m
В описании hpa
при изменении метрик видим события вида:
Normal SuccessfulRescale 11m horizontal-pod-autoscaler New size: 1; reason: All metrics below target Normal SuccessfulRescale 2m50s (x2 over 63m) horizontal-pod-autoscaler New size: 4; reason: external metric s0-metric-api-trigger_metric{foo="bar"}(&LabelSelector{MatchLabels:map[string]string{scaledobject.keda.sh/name: my-scaler,},MatchExpressions:[]LabelSelectorRequirement{},}) above target
Работает!
Выводы
Думаю, все уже поняли, что в данной интеграции вместо Yandex Monitoring может быть любой http-эндпоинт, который будет опрашиваться scaledobject
с заданной периодичностью. Главное, чтобы метрики были в нужном формате: yaml, json, prometheus или xml. Это дает неограниченное количество интеграций масштабирования всего и вся. Например, приложение может отдавать метрику по http, hpa будет принимать решение о масштабировании.
При этом нам не нужно хранить метрику! Достаточно её оперативно и регулярно отдавать по http, чтобы контроллер принял решение о количестве запущенных подов.
ссылка на оригинал статьи https://habr.com/ru/articles/852860/
Добавить комментарий