ResourceQuota и LimitRange в Kubernetes: готовые примеры для ограничения CPU, памяти и pod | AdminWiki
Timeweb Cloud — сервера, Kubernetes, S3, Terraform. Лучшие цены IaaS.
Попробовать

ResourceQuota и LimitRange в Kubernetes: готовые примеры для ограничения CPU, памяти и pod

25 мая 2026 6 мин. чтения

Зачем нужны ResourceQuota и LimitRange: защита кластера от хаоса

Одно развертывание с ошибкой в конфигурации или агрессивное приложение может занять все доступные CPU и память узла, вызвав отказ других критичных сервисов. Эта проблема, известная как "noisy neighbor", угрожает стабильности всего кластера. ResourceQuota и LimitRange - стандартные инструменты Kubernetes для изоляции и гарантии доступности ресурсов.

ResourceQuota работает как жесткий бюджет для всего namespace, ограничивая суммарное потребление CPU, памяти и количество объектов. LimitRange задает правила для каждого pod или container, определяя допустимые запросы и лимиты ресурсов. Если провести аналогию с бизнес-процессами, ResourceQuota - это лимит трат по карте на отдел, а LimitRange - регламент оформления каждого заказа.

ResourceQuota: устанавливаем жесткий лимит ресурсов для namespace

ResourceQuota изолирует команды и проекты на уровне namespace, предотвращая исчерпание ресурсов одним приложением. Этот объект ограничивает два типа ресурсов: вычислительные (requests.cpu, limits.cpu, requests.memory, limits.memory) и количество объектов Kubernetes (pods, persistentvolumeclaims, services). Планировщик Kubernetes проверяет оставшуюся квоту перед созданием нового pod и отклоняет запрос, если его выполнение превысит установленные лимиты.

Готовый манифест ResourceQuota с пояснениями

Создайте файл resource-quota.yaml со следующим содержимым:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-quota
  namespace: production-team-a
spec:
  hard:
    pods: "10"
    persistentvolumeclaims: "5"
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"

Разберем секцию spec.hard построчно:

  • pods: "10" - максимальное количество pod в namespace production-team-a не может превышать 10.
  • persistentvolumeclaims: "5" - ограничивает количество PersistentVolumeClaim (PVC) до 5.
  • requests.cpu: "4" - суммарный запрос CPU от всех pod не должен превышать 4 ядра.
  • requests.memory: "8Gi" - суммарный запрос памяти ограничен 8 ГиБ.
  • limits.cpu: "8" - суммарный лимит CPU для всех контейнеров - 8 ядер.
  • limits.memory: "16Gi" - суммарный лимит памяти - 16 ГиБ.

Примените манифест командой: kubectl apply -f resource-quota.yaml. Важно помнить, что квота применяется ко всем pod в namespace, включая системные, если они там находятся. Для системных namespace вроде kube-system квоты обычно не устанавливают.

Что происходит при нарушении квоты

Попытка создать pod, который превышает доступную квоту, будет немедленно отклонена API Kubernetes. Вы получите ошибку вида: Error from server (Forbidden): pods "web-app" is forbidden: exceeded quota: team-a-quota, requested: limits.cpu=2, limits.memory=2Gi, used: limits.cpu=7.5, limits.memory=15Gi, limited: limits.cpu=8, limits.memory=16Gi.

Чтобы проверить текущее использование квот, выполните команду kubectl describe resourcequota team-a-quota -n production-team-a. В выводе вы увидите разделы Used и Hard. Стратегия - устанавливать квоты с разумным запасом, но ниже общих лимитов кластера, чтобы сохранить ресурсы для других namespace. Для автоматизации этого процесса можно интегрировать создание квот в CI/CD пайплайн или инструменты IaC.

LimitRange: задаем разумные defaults и limits для pod и container

LimitRange решает проблему, когда разработчики не указывают requests и limits в манифестах. Это приводит к непредсказуемому планированию pod и потенциальному конфликту за ресурсы. Объект LimitRange, действующий внутри namespace, принудительно задает правила для каждого создаваемого container или pod.

Его основные функции: установка значений по умолчанию для limits (default) и запросов (defaultRequest), если они не указаны явно, а также определение минимальных (min) и максимальных (max) допустимых значений. LimitRange может быть типа Container, Pod или PersistentVolumeClaim.

Пример настройки LimitRange для container

Создайте файл limit-range.yaml:

apiVersion: v1
kind: LimitRange
metadata:
  name: container-limits
  namespace: production-team-a
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "1Gi"
    defaultRequest:
      cpu: "200m"
      memory: "512Mi"
    type: Container

Секция limits содержит правила. Параметр type: Container указывает, что правило применяется к каждому контейнеру в pod. Поля default определяют лимиты CPU и памяти, которые будут автоматически проставлены контейнеру, если они не заданы в его манифесте. В нашем примере это 500 миллиядер CPU и 1 ГиБ памяти. Поля defaultRequest задают соответствующие запросы ресурсов - 200m CPU и 512 МиБ памяти.

Эффект простой: если разработчик создаст pod с контейнером, в манифесте которого нет секции resources, Kubernetes автоматически дополнит ее значениями из LimitRange. Это гарантирует, что все контейнеры будут иметь предсказуемые лимиты, что критично для корректной работы Deployment и планировщика.

Как LimitRange и ResourceQuota работают вместе

LimitRange и ResourceQuota - не альтернативы, а взаимодополняющие инструменты для комплексной защиты кластера. LimitRange осуществляет микроконтроль, задавая правила для каждого объекта. ResourceQuota выполняет макроконтроль, устанавливая потолок потребления для всего namespace.

Их совместная работа создает надежную схему: LimitRange гарантирует, что у каждого создаваемого pod есть адекватные limits и requests (даже проставленные по умолчанию). ResourceQuota, в свою очередь, следит, чтобы сумма всех limits и requests в namespace не превысила выделенный лимит. Идеальная практика - всегда использовать их в паре: LimitRange обеспечивает наличие limits, а ResourceQuota защищает от их суммарного превышения.

Практика: настраиваем управление ресурсами с нуля

Соберем знания в пошаговый сценарий для тестового окружения.

  1. Создайте namespace для демонстрации: kubectl create ns resource-demo.
  2. Примените манифест LimitRange, чтобы задать defaults для контейнеров (используйте YAML из примера выше, изменив namespace).
  3. Примените манифест ResourceQuota, чтобы установить жесткие квоты для этого namespace.
  4. Попробуйте развернуть простой pod без указания resources. Например, создайте файл test-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  namespace: resource-demo
spec:
  containers:
  - name: nginx
    image: nginx:alpine

После применения (kubectl apply -f test-pod.yaml) проверьте созданный pod: kubectl get pod test-pod -n resource-demo -o yaml. В секции resources контейнера вы увидите значения, автоматически подставленные из LimitRange (cpu: 500m, memory: 1Gi и соответствующие requests).

  1. Попробуйте превысить квоту. Создайте deployment, который запрашивает больше памяти, чем доступно по квоте, или попытайтесь создать 11-й pod при квоте в 10. Команда kubectl вернет ошибку "exceeded quota".

Вывод: кластер защищен. Планировщик не допустит создания объектов, нарушающих установленные правила.

Частые ошибки и как их избежать

Опыт внедрения выявляет типичные проблемы:

  • Слишком жесткие квоты блокируют обновления. Deployment не может выполнить rolling update, потому что для создания нового pod с новой версией нет квоты (старый pod еще не удален). Решение - всегда оставлять запас в 1-2 pod в квоте для операций обновления и перезапуска.
  • Некорректная логика LimitRange. Установка значения max меньше, чем default, приведет к ошибкам при создании любого контейнера. Решение - проверять манифест на соответствие логике: min ≤ defaultRequest ≤ default ≤ max.
  • Игнорирование системных pod. Применение квот к namespace kube-system может заблокировать запуск системных компонентов Kubernetes. Решение - не устанавливать ResourceQuota для системных namespace или явно исключать их из подсчета при планировании ресурсов кластера.

Всегда проверяйте текущую конфигурацию: kubectl describe limitrange -n <namespace> и kubectl describe resourcequota -n <namespace>. Для сложных кастомных ресурсов аналогичные принципы валидации и отладки описаны в гайде по полной диагностике CR.

Проверка актуальности: для каких версий Kubernetes это работает

Приведенные манифесты используют stable API (apiVersion: v1), который поддерживается много лет. Базовая логика работы ResourceQuota и LimitRange неизменна с версий Kubernetes примерно 1.10. Ключевые поля, такие как requests.cpu, limits.memory, pods, остаются стандартными и обратно совместимыми.

Для абсолютной уверенности в актуальности синтаксиса для вашей конкретной minor-версии (например, 1.28) сверьтесь с официальной документацией Kubernetes. Однако для production-задач, связанных с хранением данных, также стоит изучить современные практики управления PersistentVolume, количество которых также регулируется квотами.

Итог: стабильный кластер под контролем

ResourceQuota - главный инструмент для изоляции команд и проектов в Kubernetes. Он предотвращает исчерпание критичных ресурсов одним приложением, обеспечивая базовую стабильность и предсказуемость среды. LimitRange - обязательный инструмент для enforcement policy, гарантирующий, что у всех pod и контейнеров есть адекватные limits и requests, даже если разработчики их не указали.

Используя эти механизмы вместе, вы создаете защищенную и управляемую среду, где ресурсы распределены справедливо, а планировщик может эффективно размещать workload. Следующий практический шаг - внедрить эту схему в CI/CD пайплайн для автоматического создания namespace с предустановленными квотами и лимитами для каждого нового проекта или микросервиса, как часть общей стратегии оркестрации. Это снизит операционную нагрузку и исключит человеческий фактор при развертывании.

Поделиться:
Сохранить гайд? В закладки браузера