Kubernetes v1.37 включає підтримку API для горизонтального автоматичного масштабування навантажень до нуля реплік. Ця функція тепер перебуває в стані бета та є стандартно увімкненою. HorizontalPodAutoscaler (HPA), який використовує відповідний обʼєкт метрик або зовнішні метрики, тепер може масштабувати навантаження до нуля реплік, а потім відновлювати його, коли метрика змінюється.
До v1.37 для масштабування від нуля потрібена була надбудова або зовнішній компонент, або увімкнення функціональної можливості Alpha-рівня. Тепер це частина ядра Kubernetes.
Масштабування до нуля призводить до видалення останнього неактивного Podʼа із робочих навантажень, таких як споживачі черг та пакетні процесори. Економія є найбільшою, коли кожен Pod резервує ресурси з високою вартістю, зокрема виділені процесори (CPU) або графічні процесори (GPU).
Компроміс — час холодного запуску: HPA повинен стежити за метрикою, запланувати Pod і запустити застосунок. Це добре працює, коли завдання можуть очікувати у довготривалій черзі.
Kubernetes Services не буферизують запити, поки жоден Pod не є готовим, тому для HTTP та інших робочих навантажень, що базуються на запитах, потрібен окремий рівень буферизації.
HPA часто масштабується на основі використання CPU або памʼяті. Обидві метрики надходять від запущених Podʼів. Коли кількість реплік досягає нуля, не залишається жодного Podʼа для вимірювання та жодного сигналу, який міг би сказати HPA масштабуватися знову вгору.
Обʼєктні та зовнішні метрики не мають цього обмеження. Довжина черги, наприклад, існує незалежно від обробників, які її обробляють. HPA може продовжувати читати довжину черги, коли жоден обробник не запущений.
Наступний приклад масштабує обробників черги від і до нуля, використовуючи зовнішню метрику.
Наступний приклад використовує метрику Prometheus з назвою queue_consumer_lag. Припускається, що Prometheus вже збирає серію, схожу на цю:
queue_consumer_lag{namespace="default",name="worker_tasks"}
Kubernetes потрібен адаптер метрик, щоб зробити це значення доступним через API зовнішніх метрик. Однією з реалізацій є Prometheus Adapter, який може експонувати серію, використовуючи запис externalRules:
externalRules:
- seriesQuery: '{__name__="queue_consumer_lag",name!=""}'
metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (name)
resources:
overrides:
namespace:
resource: namespace
Точна інсталяція адаптера та правила виявлення залежать від налаштування вашого моніторингу. Дивіться керівництво Prometheus Adapter щодо зовнішніх метрик для варіантів докладної конфігурації.
Перед створенням HPA ви можете перевірити, чи Kubernetes може прочитати метрику:
kubectl get --raw \
'/apis/external.metrics.k8s.io/v1beta1/namespaces/default/queue_consumer_lag?labelSelector=name%3Dworker_tasks'
Запит має повернути поточне значення для worker_tasks. Якщо це не так, виправте конвеєр метрик перед налаштуванням HPA. HPA не може масштабуватися від нуля, коли його метрика недоступна.
Наступний HPA націлений на Deployment з назвою queue-worker. Він дозволяє мати від нуля до десяти реплік, з однією реплікою, запитуваною на кожні 30 завдань у черзі:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: queue-worker
annotations:
kubernetes.io/description: "Масштабує queue-worker на основі кількості завдань у черзі"
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: queue-worker
minReplicas: 0
maxReplicas: 10
metrics:
- type: External
external:
metric:
name: queue_consumer_lag
selector:
matchLabels:
name: worker_tasks
target:
type: Value
value: "30"
Коли черга порожня, HPA може зменшити Deployment до нуля реплік. Коли завдання надходять, зовнішня метрика залишається доступною, і HPA розраховує нову кількість реплік, обмежену десятьма maxReplicas.
Запустіть Deployment із щонайменше однією реплікою. Ручне встановлення кількості реплік у Deployment на нуль завжди призупиняло автоматичне масштабування. HPA зберігає цю поведінку і не буде активувати робоче навантаження, яке воно не зменшило самостійно.
Звичайна поведінка HPA все ще застосовується. Зокрема, вікно стабілізації зменшення зазвичай становить пʼять хвилин. Вікно запобігає тому, що коротке зменшення довжини черги негайно видаляє всіх обробників. Ви можете налаштувати вікно через spec.behavior.scaleDown, якщо ваше навантаження потребує іншої поведінки.
Масштабування від нуля створює неоднозначність. Кількість реплік, рівна нулю, може означати, що HPA зменшив навантаження, або що оператор вручну призупинив його.
Контролер вирішує це за допомогою стану статусу ScaledToZero. Коли HPA масштабує навантаження від однієї або більше реплік до нуля, він записує ScaledToZero=True. Стан повідомляє наступним циклам узгодження, що контролер володіє статусом нуля і має продовжувати оцінювати метрики обʼєктів або зовнішні метрики.
Після масштабування навантаження знову вгору, контролер змінює стан на ScaledToZero=False з причиною NotScaledToZero. Навантаження на нулі без стану ScaledToZero=True залишається призупиненим.
Ви можете перевірити стани за допомогою:
kubectl describe hpa queue-worker
Якщо адаптер не може повернути налаштовану метрику, HPA повідомляє ScalingActive=False з причиною, такою як FailedGetExternalMetric. Відновіть метрику або вручну масштабуйте навантаження, щоб відновити його.
У Kubernetes v1.37 функціональна можливість HPAScaleToZero є стандартно увімкненою як на kube-apiserver, так і на kube-controller-manager. API сервер приймає minReplicas: 0; контролер-менеджер виконує масштабування на основі станів.
Під час оновлення панелі управління, коли версії компонентів не збігаються, перед створенням HPA з параметром minReplicas: 0 слід дочекатися, поки обидва компоненти почнуть підтримувати цю функцію та увімкнуть її. Контролер-менеджер з вимкненою функцією трактує replicas: 0 як ручну паузу і може залишити навантаження на нулі.
Перед вимкненням функціональної можливості або відкочуванням до версії без реалізації на основі станів:
minReplicas: 1 або вище.minReplicas: 0 також вимагає принаймні одну метрику обʼєкту або зовнішню метрику. API сервер відхиляє HPA, який містить лише ресурсні метрики, такі як CPU або памʼять.
Перша Alpha реалізація вийшла в Kubernetes v1.16. Kubernetes v1.36 додав стан ScaledToZero та поведінку контролера, необхідну для розрізнення автоматичного масштабування вниз від ручної паузи.
Kubernetes v1.37 зробив цю функцію стандартно увімкненою після додавання інтеграційного та наскрізного покриття для масштабування до нуля та назад з зовнішньої метрики. Наступний крок — отримання та збір операційного зворотного відгуку перед розглядом переходу до GA.
Ця функція належить SIG Autoscaling. Приєднуйтесь до Kubernetes Slack та каналу #sig-autoscaling, щоб поділитися зворотним звʼязком від використання Beta.
Дякуємо учасникам SIG Autoscaling, які допрацювали цю функцію — від початкової реалізації у версії 1.16 до переробки на основі станів та переходу до бета-версії. Дякуємо також Guy Templeton та Adrian Moisey за огляд KEP, а також рецензентам релізу, документації та production-readiness, які допомогли підготувати її для Kubernetes v1.37.