# Kubernetes v1.37: Масштабування навантажень до нуля за допомогою HorizontalPodAutoscaler

LLMS index: [llms.txt](/llms.txt)

---

Kubernetes v1.37 включає підтримку API для горизонтального автоматичного масштабування навантажень до нуля реплік. Ця функція тепер перебуває в стані бета та є стандартно увімкненою. [HorizontalPodAutoscaler](/docs/concepts/workloads/autoscaling/horizontal-pod-autoscale/) (HPA), який використовує відповідний _обʼєкт метрик_ або _зовнішні метрики_, тепер може масштабувати навантаження до нуля реплік, а потім відновлювати його, коли метрика змінюється.

До v1.37 для масштабування від нуля потрібена була надбудова або зовнішній компонент, або увімкнення функціональної можливості Alpha-рівня. Тепер це частина ядра Kubernetes.

Масштабування до нуля призводить до видалення останнього неактивного Podʼа із робочих навантажень, таких як споживачі черг та пакетні процесори. Економія є найбільшою, коли кожен Pod резервує ресурси з високою вартістю, зокрема виділені процесори (CPU) або графічні процесори (GPU).

Компроміс — час холодного запуску: HPA повинен стежити за метрикою, запланувати Pod і запустити застосунок. Це добре працює, коли завдання можуть очікувати у довготривалій черзі.

Kubernetes Services не буферизують запити, поки жоден Pod не є готовим, тому для HTTP та інших робочих навантажень, що базуються на запитах, потрібен окремий рівень буферизації.

## Чому масштабування від нуля потребує іншої метрики {#why-scaling-from-zero-needs-a-different-metric}

HPA часто масштабується на основі використання CPU або памʼяті. Обидві метрики надходять від запущених Podʼів. Коли кількість реплік досягає нуля, не залишається жодного Podʼа для вимірювання та жодного сигналу, який міг би сказати HPA масштабуватися знову вгору.

Обʼєктні та зовнішні метрики не мають цього обмеження. Довжина черги, наприклад, існує незалежно від обробників, які її обробляють. HPA може продовжувати читати довжину черги, коли жоден обробник не запущений.

Наступний приклад масштабує обробників черги від і до нуля, використовуючи зовнішню метрику.

## Налаштування зовнішньої метрики {#configure-an-external-metric}

Наступний приклад використовує метрику Prometheus з назвою `queue_consumer_lag`. Припускається, що Prometheus вже збирає серію, схожу на цю:

```promql
queue_consumer_lag{namespace="default",name="worker_tasks"}
```

Kubernetes потрібен адаптер метрик, щоб зробити це значення доступним через API зовнішніх метрик. Однією з реалізацій є [Prometheus Adapter](https://github.com/kubernetes-sigs/prometheus-adapter), який може експонувати серію, використовуючи запис `externalRules`:

```yaml
externalRules:
- seriesQuery: '{__name__="queue_consumer_lag",name!=""}'
  metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (name)
  resources:
    overrides:
      namespace:
        resource: namespace
```

Точна інсталяція адаптера та правила виявлення залежать від налаштування вашого моніторингу. Дивіться керівництво Prometheus Adapter щодо [зовнішніх метрик](https://github.com/kubernetes-sigs/prometheus-adapter/blob/v0.12.0/docs/externalmetrics.md) для варіантів докладної конфігурації.

Перед створенням HPA ви можете перевірити, чи Kubernetes може прочитати метрику:

```shell
kubectl get --raw \
  '/apis/external.metrics.k8s.io/v1beta1/namespaces/default/queue_consumer_lag?labelSelector=name%3Dworker_tasks'
```

Запит має повернути поточне значення для `worker_tasks`. Якщо це не так, виправте конвеєр метрик перед налаштуванням HPA. HPA не може масштабуватися від нуля, коли його метрика недоступна.

## Налаштування HPA {#configure-the-hpa}

Наступний HPA націлений на Deployment з назвою `queue-worker`. Він дозволяє мати від нуля до десяти реплік, з однією реплікою, запитуваною на кожні 30 завдань у черзі:

```yaml
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 розрізняє нуль від призупинки {#how-the-hpa-distinguishes-zero-from-paused}

Масштабування від нуля створює неоднозначність. Кількість реплік, рівна нулю, може означати, що HPA зменшив навантаження, або що оператор вручну призупинив його.

Контролер вирішує це за допомогою стану статусу `ScaledToZero`. Коли HPA масштабує навантаження від однієї або більше реплік до нуля, він записує `ScaledToZero=True`. Стан повідомляє наступним циклам узгодження, що контролер володіє статусом нуля і має продовжувати оцінювати метрики обʼєктів або зовнішні метрики.

Після масштабування навантаження знову вгору, контролер змінює стан на `ScaledToZero=False` з причиною `NotScaledToZero`. Навантаження на нулі без стану `ScaledToZero=True` залишається призупиненим.

Ви можете перевірити стани за допомогою:

```shell
kubectl describe hpa queue-worker
```

Якщо адаптер не може повернути налаштовану метрику, HPA повідомляє `ScalingActive=False` з причиною, такою як `FailedGetExternalMetric`. Відновіть метрику або вручну масштабуйте навантаження, щоб відновити його.

## Перед оновленням або відкочуванням {#before-upgrading-or-rolling-back}

У Kubernetes v1.37 функціональна можливість `HPAScaleToZero` є стандартно увімкненою як на `kube-apiserver`, так і на `kube-controller-manager`. API сервер приймає `minReplicas: 0`; контролер-менеджер виконує масштабування на основі станів.

Під час оновлення панелі управління, коли версії компонентів не збігаються, перед створенням HPA з параметром `minReplicas: 0` слід дочекатися, поки обидва компоненти почнуть підтримувати цю функцію та увімкнуть її. Контролер-менеджер з вимкненою функцією трактує `replicas: 0` як ручну паузу і може залишити навантаження на нулі.

Перед вимкненням функціональної можливості або відкочуванням до версії без реалізації на основі станів:

- Змініть зазначені HPA на `minReplicas: 1` або вище.
- Масштабуйте будь-яке навантаження, що зараз на нулі, принаймні до однієї репліки.

`minReplicas: 0` також вимагає принаймні одну метрику обʼєкту або зовнішню метрику. API сервер відхиляє HPA, який містить лише ресурсні метрики, такі як CPU або памʼять.

## Від Alpha до Beta {#from-alpha-to-beta}

Перша Alpha реалізація вийшла в Kubernetes v1.16. Kubernetes v1.36 додав стан `ScaledToZero` та поведінку контролера, необхідну для розрізнення автоматичного масштабування вниз від ручної паузи.

Kubernetes v1.37 зробив цю функцію стандартно увімкненою після додавання інтеграційного та наскрізного покриття для масштабування до нуля та назад з зовнішньої метрики. Наступний крок — отримання та збір операційного зворотного відгуку перед розглядом переходу до GA.

## Як дізнатися більше? {#how-can-i-learn-more}

- Прочитайте документацію для [масштабування від і до нуля](/docs/concepts/workloads/autoscaling/horizontal-pod-autoscale/#scaling-to-and-from-zero).
- Прочитайте [KEP-2021: HPA supports scaling to and from zero pods for object and external metrics](https://kep.k8s.io/2021).
- Дізнайтеся, як налаштувати [Prometheus Adapter для зовнішніх метрик](https://github.com/kubernetes-sigs/prometheus-adapter/blob/v0.12.0/docs/externalmetrics.md).

## Як приєднатися {#how-to-get-involved}

Ця функція належить [SIG Autoscaling](https://www.kubernetes.dev/community/community-groups/sigs/autoscaling/). Приєднуйтесь до [Kubernetes Slack](https://slack.k8s.io/) та каналу [`#sig-autoscaling`](https://kubernetes.slack.com/archives/C09R1LV8S), щоб поділитися зворотним звʼязком від використання Beta.

## Подяки {#acknowledgements}

Дякуємо учасникам SIG Autoscaling, які допрацювали цю функцію — від початкової реалізації у версії 1.16 до переробки на основі станів та переходу до бета-версії. Дякуємо також [Guy Templeton](https://github.com/gjtempleton) та [Adrian Moisey](https://github.com/adrianmoisey) за огляд KEP, а також рецензентам релізу, документації та production-readiness, які допомогли підготувати її для Kubernetes v1.37.
