Как ограничить ресурсы CPU и памяти для pod?
Как ограничить ресурсы CPU и памяти для Pod в Kubernetes
Основные понятия — requests и limits
-
requests — гарантия ресурсов для планировщика: сумма запросов контейнеров учитывается при решении, на какой ноде разместить Pod.
-
limits — верхний предел потребления, применяемый на уровне cgroup: если контейнер попытается превысить limit по CPU — он будет троттлиться (ограничиваться), по памяти — будет убит (OOMKilled).
Единицы: CPU задаётся в ядрах или мили-ядрах (1 = 1 ядро, 500m = 0.5 ядра). Память — в байтах с суффиксами Ki, Mi, Gi и т.д. (128Mi, 1Gi).
Где задать — в манифесте контейнера
Ограничения задаются в секции resources каждого контейнера в Pod/Deployment/StatefulSet:
containers:
\- name: app
image: myapp:latest
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
Важно: ресурсы задаются на уровне контейнера; у Pod нет отдельного поля для суммарных ограничений — суммой контейнерных значений и оперирует планировщик.
Влияние на планирование и поведение
-
Планировщик использует requests для расчёта места на ноде (учитывая allocatable).
-
Если limits.cpu задан, а использование превысило limit — контейнер будет получать меньше CPU (throttling), но не будет убит.
-
Если память превысила limits.memory, ядро/oom-killer завершит процесс контейнера, Kubernetes пометит статус OOMKilled.
-
Если requests не заданы, планировщик считает их нулевыми — Pod может быть размещён легко, но риск перемещения/эвиктов и проблем с QoS увеличивается.
QoS-классы (влияют на приоритет при эвикшене)
-
Guaranteed — для каждого контейнера заданы и requests, и limits, и значения равны для CPU и памяти. Такие Pod’ы наиболее защищены от эвикшенов.
-
Burstable — заданы requests (или limits ≠ requests) — Pod получает частичную защиту.
-
BestEffort — ни requests, ни limits не заданы — наименее защищённые, первыми под ударом при давлении на ресурсы.
Политики на уровне namespace/кластера
-
LimitRange — задаёт дефолты, min/max значения и defaultRequest/defaultLimit в namespace; полезно, чтобы заставить разработчиков не забывать requests/limits. Пример (коротко): defaultRequest: cpu: "250m", memory: "256Mi".
-
ResourceQuota — ограничивает суммарные ресурсы в namespace (например, requests.cpu: "10", limits.memory: "20Gi"), предотвращая перепотребление.
Практические рекомендации
-
Всегда указывайте и requests, и limits для production-контейнеров.
-
Для стабильного QoS ставьте request == limit, если нужен Guaranteed.
-
Для приложений с пиковым характером можно давать меньший request и больший limit (burstable), но мониторьте throttling и OOM.
-
Проверяйте метрики (kubectl top pod с metrics-server) и логи OOMKilled (kubectl describe pod) при проблемах.
-
Используйте LimitRange чтобы стандартизировать значения в namespace и ResourceQuota для контролируемого мультиарендного окружения.
-
HPA (Horizontal Pod Autoscaler) по умолчанию опирается на использование CPU относительно requests — корректно заданные requests важны для правильного масштабирования.
Диагностика проблем
-
CPU-троттлинг: смотреть kubectl describe pod, kubectl top pod, прометей/метрики контроллера; высокая разница между usage и limits → возможны задержки.
-
OOMKilled: kubectl describe pod покажет статус OOMKilled и причину; анализировать потребление памяти и увеличить limits.memory или оптимизировать приложение.
-
Непланируемая плотность на ноде: проверять kubectl describe node (allocatable vs requests sum).