KEDA: Enforced scaled to zero with Keda
С HPA ты привык к простой магии: `kubectl scale deployment my-deployment --replicas=0`. Поды ушли, деплоймент заснул. Потом `--replicas=3` — и жизнь возвращаетс
С HPA ты привык к простой магии: kubectl scale deployment my-deployment --replicas=0. Поды ушли, деплоймент заснул. Потом --replicas=3 — и жизнь возвращается, HPA снова подхватывает управление. Это как поставить чайник на паузу.
С KEDA эта магия ломается. Ты пытаешься сделать то же самое, но реплики упрямо возвращаются обратно. Или не возвращаются, но в логах KEDA начинается апокалипсис. В документации есть туманная фраза про то, что KEDA не будет вмешиваться в ручное масштабирование до нуля. На практике это часто не так.
Почему KEDA не даёт зазеркалить деплоймент
KEDA — это не просто HPA. Это оператор, который управляет HPA. Когда ты создаешь ScaledObject, KEDA генерирует и настраивает за тебя HorizontalPodAutoscaler под капотом.
Твоя команда kubectl scale меняет желаемое количество реплик у деплоймента. Но KEDA в постоянном цикле наблюдения. Он видит, что текущее состояние деплоймента (0 реплик) не соответствует тому, что он считает правильным на основе метрик из ScaledObject. И он перезаписывает твоё ручное изменение, выставляя реплики обратно на minReplicaCount.
Попытки обойти это через костыли вроде установки minReplicas: 0 и maxReplicas: 0 в самом ScaledObject — верный путь к ошибкам в логах оператора. Он не предназначен для такого.
Как всё-таки усыпить деплоймент под KEDA
Решение — обмануть KEDA, временно лишив его управления. Но не удаляя ScaledObject (потому что хранить его где-то отдельно — это костыль на костыле).
Секрет в том, что KEDA следит только за теми HPA, которые он сам создал. Он идентифицирует их по специальной метке.
Порядок действий:
- Создай ручной HPA поверх своего деплоймента. KEDA проигнорирует его, потому что не он его создавал.
- Масштабируй с помощью этого HPA до нуля. Твой ручной HPA переопределит желание KEDA.
Выглядит это так:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: my-deployment-maintenance-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-deployment # имя твоего деплоймента под управлением KEDA
minReplicas: 0
maxReplicas: 0
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 1
Примени этот манифест. KEDA продолжит суетиться со своим внутренним HPA, но приоритет будет у твоего my-deployment-maintenance-hpa с его жёсткими minReplicas: 0 и maxReplicas: 0. Деплоймент уйдёт в ноль.
Чтобы разбудить систему, просто удали этот временный HPA:
kubectl delete hpa my-deployment-maintenance-hpa
KEDA снова получит полный контроль и начнёт масштабировать на основе своих метрик, как ни в чём не бывало. ScaledObject всё это время лежал нетронутым.
Итог
KEDA — оператор с активной позицией. Чтобы его пересилить, нужно не бороться с ним в лоб, а создать параллельный контур управления. Временный ручной HPA — это твой легальный bypass на время техработ. Главное — не забыть его потом убрать.