Перейти к содержанию
Innovialabs

Requests и limits в Kubernetes: как правильно задавать ресурсы

Продвинутое3 мин

Коротко

Requests нужны планировщику, чтобы найти узел для пода, а limits — ядру, чтобы ограничить потребление. Ставьте requests по реальному использованию, memory limit — с запасом, а CPU limit — осознанно, потому что он вызывает throttling.

Коротко: requests для планирования, limits для ограничения

Requests — это то, сколько ресурсов под «бронирует» на узле. Планировщик (scheduler) размещает под только туда, где сумма requests уже запущенных подов плюс новый не превышает доступную ёмкость узла. Фактическое потребление при этом не учитывается.

Limits — это потолок, который контролирует ядро Linux через cgroups. Поведение при его достижении зависит от ресурса:

  • CPU — сжимаемый ресурс. Если контейнер упирается в CPU limit, его просто притормаживают (throttling). Процесс живёт, но отвечает медленнее.
  • Память — несжимаемый ресурс. Превысил memory limit — ядро убивает процесс, под получает статус OOMKilled и перезапускается.
resources:
  requests:
    cpu: "250m"
    memory: "256Mi"
  limits:
    memory: "512Mi"

QoS-классы и почему они важны

Kubernetes присваивает каждому поду класс качества обслуживания. От него зависит, кого выселят первым, когда на узле заканчивается память.

КлассУсловиеПриоритет при нехватке памяти
GuaranteedУ всех контейнеров requests = limits по CPU и памятиВыселяется последним
BurstableЗадан хотя бы один request или limit, но не GuaranteedСредний
BestEffortНи requests, ни limits не заданыВыселяется первым

Для баз данных и критичных сервисов имеет смысл Guaranteed. Для большинства stateless-приложений подходит Burstable. BestEffort в продакшене почти всегда ошибка.

OOMKilled и CPU throttling: как распознать

OOMKilled видно сразу:

kubectl describe pod <pod> | grep -A3 "Last State"

Причины обычно три: limit ниже реального пика, утечка памяти или runtime, который не знает о лимите контейнера (например, старые настройки JVM или неограниченный heap в Node.js).

CPU throttling коварнее: под не падает, просто растёт латентность. Признак — метрика container_cpu_cfs_throttled_periods_total растёт, хотя средняя загрузка CPU выглядит умеренной. Так бывает, когда приложение потребляет CPU всплесками: за короткий период квота исчерпывается, и потоки ждут следующего окна.

Метод подбора по реальным данным

  1. Начните с разумной оценки. Запустите сервис с умеренными requests и memory limit с запасом.
  2. Соберите метрики за типичный цикл нагрузки — минимум несколько дней, включая пиковые часы. Нужны Prometheus и cAdvisor/kubelet-метрики или аналог.
  3. CPU request ставьте около высокого перцентиля (p90–p95) реального потребления, а не по пику.
  4. Memory request — по типичному рабочему объёму, memory limit — выше наблюдаемого максимума с запасом на всплески.
  5. CPU limit решайте отдельно. Многие команды не задают его для latency-чувствительных сервисов, чтобы избежать throttling, и полагаются на requests для справедливого распределения. Если limit нужен (multi-tenant кластер, защита от «шумных соседей»), ставьте его заметно выше request.
  6. Проверьте с нагрузкой. Прогоните нагрузочный тест и посмотрите на throttling, OOM и латентность.
  7. Пересматривайте регулярно. После крупных релизов профиль потребления меняется.

Помогает Vertical Pod Autoscaler в режиме рекомендаций (updateMode: "Off"): он не меняет поды, а только подсказывает значения.

Частые ошибки

  • Requests сильно завышены. Узлы «заняты» на бумаге, но реально простаивают — вы платите за пустую ёмкость.
  • Requests занижены. Планировщик упаковывает слишком много подов на узел, они конкурируют за ресурсы, растёт риск выселения.
  • Memory limit = request «впритык». Любой всплеск — OOMKilled.
  • Одинаковые ресурсы для всех сервисов. Скопированный шаблон редко подходит и API, и воркеру очередей.
  • HPA по CPU без корректных requests. Horizontal Pod Autoscaler считает утилизацию относительно request, поэтому неверный request ломает автоскейлинг.

Частые вопросы

Не всегда. CPU limit защищает соседей по узлу, но вызывает throttling. Для сервисов, где важна задержка, часто задают только CPU request. В общих кластерах с жёсткими квотами limit бывает обязателен — тогда держите его с запасом.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.