Современные приложения часто работают с асинхронными задачами для обработки фоновых операций. Celery в сочетании с брокером сообщений (например, RabbitMQ) – одно из популярных решений для таких задач. Однако ручное управление количеством подов для обработки задач в Kubernetes – неэффективно, особенно в условиях переменной нагрузки. На помощь приходит KEDA (Kubernetes Event-Driven Autoscaling), которая позволяет масштабировать поды на основе событий, таких как длина очередей RabbitMQ.
Предположим, у нас есть сервис, который обрабатывает задачи Celery. Задачи публикуются в очереди RabbitMQ, а Celery-воркеры обрабатывают их в Kubernetes. Наша цель:
- Увеличивать количество воркеров, если длина очереди превышает определенный порог.
- Уменьшать количество воркеров, когда очередь разгружена.
Как работает скейлинг в KEDA?
- Скейлинг вверх:
- KEDA проверяет длину очереди каждые
pollingInterval
секунд. - Если длина очереди превышает значение в
queueLength
, KEDA увеличивает количество подов, но не больше значенияmaxReplicaCount
.
- KEDA проверяет длину очереди каждые
- Скейлинг вниз:
- После разгрузки очереди KEDA начинает уменьшать количество подов.
- Уменьшение происходит через интервал
cooldownPeriod
. - Количество подов не опустится ниже значения
minReplicaCount
.
Преимущества KEDA для скейлинга Celery
- Экономия ресурсов: Поды запускаются только при наличии нагрузки.
- Гибкость настройки: Можно задать различные параметры для каждой очереди.
- Масштабируемость: Удобно поддерживать различные типы задач Celery, создавая отдельные ScaledObject для каждой очереди.
Deployment Celery в kubernetes для примера:
Само собой обратите и замените на свои значения поля: name, labels, image, args. Это лишь пример обобщенного deployment celery worker’a
apiVersion: apps/v1
kind: Deployment
metadata:
name: celery-main
namespace: your-namespace
spec:
replicas: 1
selector:
matchLabels:
app: celery-main
template:
metadata:
labels:
app: celery-main
spec:
containers:
- name: celery-main
image: celery.image:latest
args: ["celery", "-A", "project", "worker", "-n", "celery@images", "-Q", "images_queue", "-E", "--concurrency=1", "--pool=threads", "--time-limit=7200"]
resources:
limits:
cpu: "500m"
memory: "256Mi"
requests:
cpu: "250m"
memory: "128Mi"
Далее в кластер нам необходимо установить KEDA оператора, сделать это можно с помощью helm:
helm install keda kedacore/keda --namespace keda --create-namespace
Настройка ScaledObject для KEDA
ScaledObject – это ресурс KEDA, который описывает правила автоматического скейлинга подов. Вот пример настройки:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: celery-main-scaler
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: celery-main # Имя деплоймента celery
pollingInterval: 30 # Частота проверки длины очереди (сек.)
cooldownPeriod: 300 # Задержка перед уменьшением числа подов (сек.)
minReplicaCount: 1 # Минимальное количество подов
maxReplicaCount: 10 # Максимальное количество подов
triggers:
- type: rabbitmq
metadata:
queueName: "images_queue" # Название очереди RabbitMQ
hostFromEnv: RABBITMQ_HOST
queueLength: "10" # Порог длины очереди для скейлинга
authenticationRef:
name: rabbitmq-trigger-auth
Разбор конфигурации:
scaleTargetRef
: Указывает на деплоймент Celery, который нужно масштабировать.pollingInterval
: Определяет частоту проверки состояния очереди.cooldownPeriod
: Задает время ожидания перед уменьшением количества подов, чтобы избежать частого переключения.minReplicaCount
иmaxReplicaCount
: Указывают минимальное и максимальное количество подов.triggers
:- Тип триггера (
rabbitmq
). - Название очереди, длину которой нужно мониторить.
- Переменная окружения (
hostFromEnv
), которая содержит адрес RabbitMQ. - Порог длины очереди (
queueLength
), превышение которого запускает скейлинг.
- Тип триггера (
Подключение аутентификации
Для связи KEDA с RabbitMQ используется TriggerAuthentication:
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: rabbitmq-trigger-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
Создаем secret для подключения KEDA к Rabbitmq
apiVersion: v1
kind: Secret
metadata:
name: rabbitmq-secret
namespace: default
type: Opaque
data:
host: cmtvcmJiaXQxLmNvbQ== # base64-encoded "rabbit1.com" замените на адрес вашего кролика
username: YWRtaW4= # base64-encoded "admin" замените на юзернейм
password: cGFzc3dvcmQ= # base64-encoded "password"замените на пароль
Частые ошибки и их решение
1. Ошибка: «NOT_FOUND — no queue ‘celery’ in vhost ‘/'»
Причина: Некорректно указан vhost RabbitMQ. По умолчанию используется "/"
. Решение: Укажите корректный vhost в триггере:
metadata:
queueName: "celery"
hostFromEnv: RABBITMQ_HOST
vhost: "my_vhost"
2. Ошибка подключения к RabbitMQ
Причина: Неверные параметры аутентификации. Решение: Проверьте секрет, используемый в TriggerAuthentication
.
3. Поды не уменьшаются при разгрузке очереди
Причина: Неверно задан cooldownPeriod
или minReplicaCount
. Решение: Убедитесь, что эти параметры соответствуют требованиям, и длина очереди действительно меньше порога.
Отправить ответ