Errors
KEDA

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, которые он сам создал. Он идентифицирует их по специальной метке.

Порядок действий:

  1. Создай ручной HPA поверх своего деплоймента. KEDA проигнорирует его, потому что не он его создавал.
  2. Масштабируй с помощью этого 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 на время техработ. Главное — не забыть его потом убрать.