На хабре уже был перевод одной из статей о KEDA. В ней автор делится делится информацией о проекте, о том как KEDA интегрируется с Prometheus, и как можно масштабировать свое демо-приложение на базе метрик получаемых с Redis, работающего внутри того же Kubernetes-кластера.
В данной статье я постараюсь быть кратким. Вместе мы познакомимся с KEDA на реальном примере всего за несколько минут. Prometheus нам не пригодится.
Немного введения
Все знают, что Kubernetes отлично работает со stateless-приложениями. Особо серьезные ребята даже запускают базы данных в кубере, а самые смелые даже в продакшне. Но чаще всего в проде используются сервисы типа RDS или же БД развернутые за пределами Kubernetes-кластера.
Для тех кто хочет масштабировать свои приложения внутри Kubernetes, но при этом использовать какие-то внешние метрики (например кол-во сообщений в AWS SQS или Kafka, соединений в PostgreSQL/MySQL/и т.д) необходимо использовать внешние (external) метрики. Чаще всего это реализуется импортом метрик в Prometheus, с помощью различных адаптеров, и последующим масштабированием приложения на основе метрик в проме.
Так вот, KEDA позволяет нам немного упростить этот процесс, не обращаясь за метриками в Prometheus. Все что нам нужно, задеплоить несколько CRD-шек, пару-тройку ямлов для описания масштабирования и доступов. В общем, сейчас покажу.

Установка KEDA
Я провожу свои эксперименты на macOS, с установленным Docker for Mac. Можете использовать все что угодно, любой кубер подойдет.
Установка KEDA простая, я использую helm:
$ helm repo add kedacore https://kedacore.github.io/charts $ helm repo update $ helm install keda kedacore/keda --namespace keda --create-namespace
Задеплоили чарт, смотрим что под KEDA-оператора и метрикc-сервера поднялись:
$ kubectl get po -n keda NAME READY STATUS RESTARTS AGE keda-operator-7fc5699d47-ng7rk 1/1 Running 0 75s keda-operator-metrics-apiserver-57fc85685f-zqnzr 1/1 Running 0 75s $ kubectl get apiservices v1beta1.external.metrics.k8s.io NAME SERVICE AVAILABLE AGE v1beta1.external.metrics.k8s.io keda/keda-operator-metrics-apiserver True 95s
Все, KEDA-оператор установлен, идем дальше.
Задеплоим «Hello World»
У Kubernetes свой «Hello World», это деплоймент nginx, давайте идти по канонам и задеплоим его:
$ kubectl create ns nginx-demo $ kubectl apply -n nginx-demo -f https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/controllers/nginx-deployment.yaml
Проверим состояние подов:
$ kg po -n nginx-demo NAME READY STATUS RESTARTS AGE nginx-deployment-66b6c48dd5-2g24q 1/1 Running 0 36s nginx-deployment-66b6c48dd5-67kgv 1/1 Running 0 36s nginx-deployment-66b6c48dd5-fj4lq 1/1 Running 0 36s
Все хорошо, в этом деплойменте 3 пода, как и положено.
Давайте сделаем так, чтобы поды масштабировались в зависимости от количества сообщений в очереди RabbitMQ.
На данный момент KEDA поддерживает 36 различных источников, на основе которых можно масштабироваться, в моем примере я выбрал RabbitMQ, просто потому что так захотел.
Немного подготовки RabbitMQ
Как я уже упоминал ранее, свои тесты я делаю на локальной машине с Docker for Mac, поэтому я хочу сымитировать реальную ситуацию, когда RabbitMQ запускается не внутри Kubernetes, а, скажем, в другой сети. Поэтому его я буду устанавливать просто через brew-пакет. Но перед этим, давайте запишем IP-адрес моей локальной машины, он нам скоро пригодится:
$ ipconfig getifaddr en0 192.168.2.101
Все, устанавливаем RabbitMQ и стартуем его:
$ brew install rabbitmq $ RABBITMQ_NODE_IP_ADDRESS=0.0.0.0 /usr/local/sbin/rabbitmq-server ... ## ## RabbitMQ 3.8.19 ## ## ########## Copyright (c) 2007-2021 VMware, Inc. or its affiliates. ###### ## ########## Licensed under the MPL 2.0. Website: https://rabbitmq.com ... Starting broker... completed with 6 plugins.
Убедимся что все поднялось:
$ /usr/local/sbin/rabbitmqadmin -H 127.0.0.1 -u guest -p guest \ list connections No items
Все хорошо. Единственный момент, что доступ под стандартным пользователем guest доступен только по адресу 127.0.0.1, поэтому нужно добавить нового пользователя, скажем (demo/demo), ну и создать очередь (demo_queue) для тестирования:
$ /usr/local/sbin/rabbitmqadmin --host 127.0.0.1 -u guest -p guest \ declare user name=demo password=demo tags=administrator user declared $ /usr/local/sbin/rabbitmqadmin --host 127.0.0.1 -u guest -p guest \ declare permission vhost=/ user=demo configure=".*" write=".*" read=".*" permission declared $ /usr/local/sbin/rabbitmqadmin --host 127.0.0.1 -u guest -p guest \ declare queue name=demo_queue queue declared
После этого мы можем подключаться по «внешнему» IP-адресу к кролику:
$ /usr/local/sbin/rabbitmqadmin -H 192.168.2.101 -u demo -p demo \ list queues +------------+----------+ | name | messages | +------------+----------+ | demo_queue | 0 | +------------+----------+
Немного YAML
RabbitMQ готов, теперь нужно подключить к нему KEDA, для этого нам надо задеплоить три объекта:
-
Secret— в нем будет храниться строка подключения к RabbitMQ, в таком виде:amqp://demo:demo@192.168.2.101:5672/ -
TriggerAuthentication— объект для аутентификации, который использует данные из секрета выше -
ScaledObject— собственно тот самый объект, в котором мы можем настраивать различные параметры масштабирования
Деплоим:
$ cat <<EOF | kubectl apply -n nginx-demo -f - --- apiVersion: v1 kind: Secret metadata: name: keda-rabbitmq-secret data: host: YW1xcDovL2RlbW86ZGVtb0AxOTIuMTY4LjIuMTAxOjU2NzIv # echo -n amqp://demo:demo@192.168.2.101:5672/ | base64 --- apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: keda-trigger-auth-rabbitmq-conn spec: secretTargetRef: - parameter: host name: keda-rabbitmq-secret # Имя нашего секрета key: host --- apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: rabbitmq-scaledobject spec: scaleTargetRef: name: nginx-deployment # Имя nginx-деплоймента который хотим масштабировать minReplicaCount: 1 # Меньше одной реплики не хотим maxReplicaCount: 5 # А то же время больше пяти тоже pollingInterval: 10 # Как часто ходить за метрикой cooldownPeriod: 120 # Сколько времени ждать для даунскейла triggers: - type: rabbitmq metadata: protocol: amqp queueName: demo_queue # Наша демо-очередь mode: QueueLength value: "3" # Если в очереди три новых сообщения — добавляем под authenticationRef: name: keda-trigger-auth-rabbitmq-conn EOF
Проверяем что все работает:
$ kubectl get scaledobject NAME SCALETARGETKIND SCALETARGETNAME MIN MAX TRIGGERS AUTHENTICATION READY ACTIVE AGE rabbitmq-scaledobject apps/v1.Deployment nginx-deployment 1 5 rabbitmq keda-trigger-auth-rabbitmq-conn True False 14m $ kubectl get po NAME READY STATUS RESTARTS AGE nginx-deployment-66b6c48dd5-24qp7 1/1 Running 0 3m46s $ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE keda-hpa-rabbitmq-scaledobject Deployment/nginx-deployment 0/3 (avg) 1 5 1 12m
Тестируем
Давайте отправим 5 сообщений в нашу очередь в RabbitMQ:
$ for i in {1..5}; do /usr/local/sbin/rabbitmqadmin --host 192.168.2.101 -u demo -p demo \ publish exchange=amq.default routing_key=demo_queue payload="message ${i}" done $ /usr/local/sbin/rabbitmqadmin -H 192.168.2.101 -u demo -p demo \ list queues +------------+----------+ | name | messages | +------------+----------+ | demo_queue | 5 | +------------+----------+
Подождем 10 секунд пока KEDA сходит за метрикой и проверим наши поды (мы ожидаем увидеть 2 пода, так как скейлимся по 1 поду, на каждые 3 сообщения в очереди):
$ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE keda-hpa-rabbitmq-scaledobject Deployment/nginx-deployment 5/3 (avg) 1 5 1 22m $ kubectl get po NAME READY STATUS RESTARTS AGE nginx-deployment-66b6c48dd5-24qp7 1/1 Running 0 14m nginx-deployment-66b6c48dd5-2d4w2 1/1 Running 0 66s
Давайте подбавим газку, добавим еще 7 сообщений в очередь:
$ for i in {6..12}; do /usr/local/sbin/rabbitmqadmin --host 192.168.2.101 -u demo -p demo \ publish exchange=amq.default routing_key=demo_queue payload="message ${i}" done $ /usr/local/sbin/rabbitmqadmin -H 192.168.2.101 -u demo -p demo \ list queues +------------+----------+ | name | messages | +------------+----------+ | demo_queue | 12 | +------------+----------+
12 сообщений в очереди, по идее уже 4 пода должно работать, проверяем:
$ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE keda-hpa-rabbitmq-scaledobject Deployment/nginx-deployment 12/3 (avg) 1 5 2 24m $ kubectl get po NAME READY STATUS RESTARTS AGE nginx-deployment-66b6c48dd5-24qp7 1/1 Running 1 17m nginx-deployment-66b6c48dd5-78d54 1/1 Running 0 38s nginx-deployment-66b6c48dd5-jxtr8 1/1 Running 0 38s nginx-deployment-66b6c48dd5-sl4p8 1/1 Running 0 38s
Теперь очистим очередь, количество подов должно опуститься до минимального значения (что в нашем случае 1 под):
$ /usr/local/sbin/rabbitmqadmin -H 192.168.2.101 -u demo -p demo \ purge queue name=demo_queue queue purged $ /usr/local/sbin/rabbitmqadmin -H 192.168.2.101 -u demo -p demo \ list queues +------------+----------+ | name | messages | +------------+----------+ | demo_queue | 0 | +------------+----------+ $ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE keda-hpa-rabbitmq-scaledobject Deployment/nginx-deployment 0/3 (avg) 1 5 1 28h $ kubectl get po NAME READY STATUS RESTARTS AGE nginx-deployment-66b6c48dd5-24qp7 1/1 Running 0 20m
Все хорошо, масштабируется и вверх и вниз, как и ожидалось.
Приберемся за собой после экспериментов:
$ helm uninstall keda -n keda $ kubectl delete ns keda $ kubectl delete ns nginx-demo
Как видите, Prometheus нам не пригодился, все максимально просто. Если пропустить момент с настройкой RabbitMQ, то процесс деплоя и тестирования KEDA занимает буквально несколько минут.
Ссылки
ссылка на оригинал статьи https://habr.com/ru/articles/569760/
Добавить комментарий