Привет, друзья-разработчики и Kubernetes-энтузиасты! Сегодня мы с вами погрузимся в мир KEDA (Kubernetes-based Event Driven Autoscaling) — инструмента, который позволит вашим приложениям масштабироваться как по волшебству.
KEDA позволяет Kubernetes автоматически масштабировать приложения на основе различных внешних событий: сообщений в очередях, метрик из Prometheus, вебхуков и многого другого. Мастхев для некоторых микросервисов.
Самый простой способ установить KEDA — применить официальный манифест:
kubectl apply -f https://github.com/kedacore/keda/releases/download/v2.10.0/keda-2.10.0.yaml
Проверьте статус подов KEDA:
kubectl get pods -n keda
Вы должны увидеть что-то вроде этого:
NAME READY STATUS RESTARTS AGE keda-operator-7d9f9f8d9b-abcde 1/1 Running 0 2m keda-operator-metrics-apiserver-xyz123 1/1 Running 0 2m
Если все поды в статусе Running
, значит, установка прошла успешно. Если нет, загляните в логи:
kubectl logs <pod-name> -n keda
Немного расскажу про сами компоненты KEDA:
ScaledObject — это центральный объект конфигурации KEDA. Он связывает приложение (например, Deployment или StatefulSet) с источниками событий, определяя условия масштабирования. В ScaledObject задаются минимальное и максимальное количество реплик, а также параметры триггеров, по которым будет происходить масштабирование.
Trigger — это источник событий или метрик, на основе которых KEDA принимает решение о масштабировании. Это может быть очередь сообщений, метрика из Prometheus или другой источник. Каждый триггер имеет свои параметры и пороги, при превышении которых инициируется масштабирование.
Scaler — компонент, отвечающий за сбор и анализ метрик из триггера. Он регулярно опрашивает источник событий, сравнивает полученные данные с заданными порогами и сообщает оператору о необходимости изменения количества реплик. Каждый тип триггера имеет свой собственный Scaler, оптимизированный для работы с конкретным источником данных.
TriggerAuthentication — объект, обеспечивающий безопасное хранение и доступ к данным подключения к внешним системам. Он содержит конфиденциальную информацию, такую как имена пользователей и пароли, необходимые для взаимодействия с триггерами. TriggerAuthentication гарантирует, что KEDA может безопасно получать доступ к ресурсам.
KEDA Operator — основной компонент, управляющий жизненным циклом ScaledObject и TriggerAuthentication. Он следит за изменениями в этих объектах, инициализирует соответствующие Scaler и взаимодействует с Kubernetes API для масштабирования приложений.
Metrics Server — агрегатор метрик внутри Kubernetes, который собирает данные о ресурсах, используемых подами и узлами. KEDA использует эти метрики для принятия решений о масштабировании, дополняя информацию от внешних триггеров.
Масштабирование п очереди RabbitMQ
Рассмотрим пошаговый пример настройки KEDA для масштабирования приложения на основе количества сообщений в очереди RabbitMQ.
Создадим простой Deployment для приложения, которое будет обрабатывать задачи из очереди RabbitMQ. Предположим, есть Docker-образ myregistry/task-processor:latest
:
# deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: task-processor labels: app: task-processor spec: replicas: 1 selector: matchLabels: app: task-processor template: metadata: labels: app: task-processor spec: containers: - name: processor image: myregistry/task-processor:latest ports: - containerPort: 8080 env: - name: RABBITMQ_HOST value: "my-rabbitmq" - name: RABBITMQ_QUEUE value: "tasks"
Применим манифест:
kubectl apply -f deployment.yaml
Для безопасного хранения данных подключения создадим Kubernetes Secret.
# secret.yaml apiVersion: v1 kind: Secret metadata: name: rabbitmq-secret type: Opaque data: host: bXktcmFiYmF0bXFoYXN0Cg== # закодировано в base64, например, echo -n 'my-rabbitmq' | base64 username: YWRtaW4= # admin password: cGFzc3dvcmQ= # password
Применим секрет:
kubectl apply -f secret.yaml
Создадим объект TriggerAuthentication
, который будет использоваться для безопасного подключения к RabbitMQ.
# triggerauth.yaml apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: rabbitmq-auth namespace: default spec: secretTargetRef: - parameter: host name: rabbitmq-secret key: host - parameter: username name: rabbitmq-secret key: username - parameter: password name: rabbitmq-secret key: password
Применим манифест:
kubectl apply -f triggerauth.yaml
Теперь создадим ScaledObject
, который будет отслеживать очередь RabbitMQ и масштабировать наше приложение в зависимости от количества сообщений.
# scaledobject.yaml apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: task-processor-scaledobject namespace: default spec: scaleTargetRef: kind: Deployment name: task-processor minReplicaCount: 1 maxReplicaCount: 10 cooldownPeriod: 300 # Время в секундах перед уменьшением числа реплик pollingInterval: 30 # Интервал проверки метрик triggers: - type: rabbitmq metadata: queueName: tasks queueLength: "5" # Порог для масштабирования authenticationRef: name: rabbitmq-auth
Применим манифест:
kubectl apply -f scaledobject.yaml
Убедимся, что все работает как надо. Напишем простой скрипт на Питоне для добавления задач в очередь и посмотрим, как KEDA реагирует на рост нагрузки.
# send_tasks.py import pika import time def main(): connection = pika.BlockingConnection(pika.ConnectionParameters('my-rabbitmq')) channel = connection.channel() channel.queue_declare(queue='tasks') for i in range(20): message = f'Task {i}' channel.basic_publish(exchange='', routing_key='tasks', body=message) print(f" [x] Sent {message}") time.sleep(1) # Пауза, чтобы видеть постепенное масштабирование connection.close() if __name__ == "__main__": main()
Запускаем скрипт:
python send_tasks.py
Открываем другой терминал и выполняем команду:
kubectl get pods -w -l app=task-processor
Можно увидеть, как количество реплик вашего приложения увеличивается по мере добавления задач в очередь:
NAME READY STATUS RESTARTS AGE task-processor-6d4d5c8c6d-abcde 1/1 Running 0 1m task-processor-6d4d5c8c6d-fghij 1/1 Running 0 30s ...
Масштабирование по HTTP-запросам с Prometheus
Рассмотрим еще один пример использования KEDA — масштабирование приложения на основе количества HTTP-запросов с Prometheus.
Создадим простой HTTP-сервис, который будет обрабатывать запросы. Предположим, есть Docker-образ myregistry/http-processor:latest
.
# http-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: http-processor labels: app: http-processor spec: replicas: 1 selector: matchLabels: app: http-processor template: metadata: labels: app: http-processor spec: containers: - name: processor image: myregistry/http-processor:latest ports: - containerPort: 8080
Применим манифест:
kubectl apply -f http-deployment.yaml
Создадим ScaledObject
, который будет масштабировать HTTP-сервис на основе метрик из Prometheus.
# http-scaledobject.yaml apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: http-processor-scaledobject namespace: default spec: scaleTargetRef: kind: Deployment name: http-processor minReplicaCount: 1 maxReplicaCount: 5 cooldownPeriod: 300 pollingInterval: 30 triggers: - type: prometheus metadata: serverAddress: http://prometheus-server.default.svc.cluster.local metricName: http_requests_total threshold: "100" # Масштабировать при превышении 100 запросов query: sum(rate(http_requests_total[2m])) by (job) > 100
Применим манифест:
kubectl apply -f http-scaledobject.yaml
Напишем скрипт для генерации HTTP-запросов к сервису.
# send_http_requests.py import requests import time def main(): url = 'http://<your-http-service-url>:8080/process' for i in range(200): response = requests.get(url) print(f" [x] Sent request {i}, Response Code: {response.status_code}") time.sleep(0.5) # Пауза между запросами if __name__ == "__main__": main()
Если вы работаете локально, используйте localhost
или соответствующий сервисный URL в кластере.
Запускаем скрипт:
python send_http_requests.py
Открываем другой терминал и выполняем команду:
kubectl get pods -w -l app=task-processor
В этом примере так же увидим, как количество реплик вашего HTTP-сервиса увеличивается по мере роста числа запросов.
В заключение приглашаем всех желающих на первые открытые уроки в этом году:
ссылка на оригинал статьи https://habr.com/ru/articles/868526/
Добавить комментарий