Сервис развивается: тестируем формат, собираем идеи, улучшаем сервис. Есть идеи? Написать
Дайджесты новостей
Инфографическая иллюстрация работы k8s-overcommit-operator, оптимизирующего запросы CPU и памяти подов в кластере Kubernetes через Admission Webhook.

Управление переподпиской ресурсов в Kubernetes: k8s-overcommit-operator

В кластерах Kubernetes разработчики микросервисов часто перестраховываются, завышая гарантированные запросы ресурсов (requests.cpu и requests.memory). Это защищает приложение от троттлинга или вытеснения, но приводит к проблеме простаивающих мощностей: планировщик Kubernetes видит узел заполненным на 100%, тогда как реальная средняя утилизация серверов не превышает 15–25%. В результате компании вынуждены оплачивать лишние виртуальные машины в облаках.

Инженерная команда InditexTech (технологическое подразделение ритейлера Inditex) опубликовала инструмент с открытым исходным кодом k8s-overcommit-operator под лицензией Apache 2.0. Оператор автоматизирует механизм переподписки (overcommit), динамически корректируя резервируемые ресурсы подов на этапе создания без изменения верхних лимитов.

Архитектура: перехват подов через Admission Webhook

Оператор реализован на языке Go и использует штатный механизм Kubernetes — Mutating Admission Webhook. Когда в API-сервер поступает запрос на создание пода, вебхук перехватывает манифест до того, как планировщик назначит его на узел.

Логика оператора опирается на две сущности:

  1. Overcommit — синглтон-ресурс кластера (обязан иметь системное имя cluster), определяющий имя управляющей метки и глобальные параметры.
  2. OvercommitClass — класс переподписки, в котором настраиваются коэффициенты сжатия requests относительно limits для разных окружений (dev, stage, prod).

Иерархия назначения классов прозрачна: оператор сначала проверяет метку на самом поде, затем — метку пространства имен, а при их отсутствии применяет дефолтный класс (isDefault: true).

apiVersion: overcommit.inditex.dev/v1alphav1
kind: Overcommit
metadata:
  name: cluster # В кластере может существовать только один ресурс с именем cluster
spec:
  overcommitLabel: inditex.com/overcommit-class
  labels:
    environment: production
---
apiVersion: overcommit.inditex.dev/v1alphav1
kind: OvercommitClass
metadata:
  name: aggressive-dev
spec:
  cpuOvercommit: 0.25      # Requests CPU составят 25% от Limits
  memoryOvercommit: 0.70   # Requests памяти составят 70% от Limits
  excludedNamespaces: ".*(^(kube-system|monitoring|k8s-overcommit).*).*"
  isDefault: false

Регулярное выражение в поле excludedNamespaces гарантирует, что системные службы Kubernetes (kube-system, компоненты мониторинга и ingress) не подвергнутся сжатию ресурсов ни при каких условиях.

Мутация манифеста на практике

Главное достоинство оператора — сохранение жестких ограничений (limits). Приложение по-прежнему имеет доступ к полной заявленной мощности при пиковых нагрузках, но планировщик рассчитывает плотность ноды по уменьшенным requests.

Рассмотрим трансформацию манифеста сервиса при прохождении через вебхук:

# Исходный манифест разработчика:
apiVersion: v1
kind: Pod
metadata:
  name: payment-worker
  namespace: stage-apps
  labels:
    inditex.com/overcommit-class: aggressive-dev
spec:
  containers:
    - name: app
      image: registry.example.com/payment:v2.1
      resources:
        limits:
          cpu: "4"
          memory: "8Gi"

---
# Манифест после применения вебхука k8s-overcommit-operator:
apiVersion: v1
kind: Pod
metadata:
  name: payment-worker
  namespace: stage-apps
  labels:
    inditex.com/overcommit-class: aggressive-dev
spec:
  containers:
    - name: app
      image: registry.example.com/payment:v2.1
      resources:
        limits:
          cpu: "4"         # Лимиты остаются нетронутыми
          memory: "8Gi"
        requests:
          cpu: "1000m"     # 4 ядра * 0.25 = 1 ядро (1000m)
          memory: "5734Mi"  # 8Gi * 0.70 = 5.6GiB

В результате на одном физическом сервере размещается заметно больше подов, что сокращает потребность в добавлении новых нод на 30–50%.

Риски и рекомендации по эксплуатации

При внедрении переподписки важно разделять поведение процессора и оперативной памяти:

  • CPU: процессор является сжимаемым ресурсом. При нехватке ядер ядро Linux применяет троттлинг (CPU throttling), распределяя такты между процессами без их аварийной остановки.
  • Память: оперативная память несжимаема. Если все поды на узле одновременно приблизятся к своим лимитам, суммарное потребление превысит емкость RAM, и активируется механизм Linux OOM Killer, завершающий процессы с низким приоритетом QoS.

По этой причине инженеры InditexTech рекомендуют выставлять cpuOvercommit агрессивно (до 0.2–0.3 для сред разработки), а параметр memoryOvercommit держать консервативным (не ниже 0.7–0.8), параллельно настраивая мониторинг утилизации нод.