ResourceQuota и LimitRange: изоляция ресурсов тенантов в Kubernetes

Когда один тенант в общем кластере запускает ресурсоёмкие задачи, остальные сервисы начинают деградировать — эффект «шумного соседа» ставит под угрозу стабильность всей инфраструктуры. Мы настраиваем ResourceQuota и LimitRange для каждого namespace, чтобы жёстко ограничить потребление и защитить соседей. Наша команда реализует проект под ключ — от аудита до мониторинга, обеспечивая надёжную изоляцию и последующую поддержку.
Часто задаваемые вопросы

Отметим: когда в мультитенантном кластере один тенант запускает resource-intensive batch job, остальные сервисы деградируют — эффект noisy-neighbor. Без квот на ресурсы вы не контролируете потребление. В кластере с 30+ тенантами 10% узлов могут использовать 200% CPU под кэшами, оставляя соседей без процессора. Единственный способ гарантировать стабильность — настроить ResourceQuota и LimitRange для каждого namespace. Наши инженеры с более чем 5-летним опытом в Kubernetes и 100+ проектами по изоляции ресурсов делают это под ключ: от аудита до мониторинга. Оценка проекта занимает 2 дня, полная реализация — от 2 до 5 дней. Средняя экономия после внедрения квот составляет $1.4k–1.9k в месяц на кластер из 30 узлов. Стоимость излишних ресурсов при отсутствии квот может достигать $2.7k–3.9k в месяц.

ResourceQuota сама по себе предотвращает около 70% случаев шумного соседства, а комбинация с LimitRange и мониторингом увеличивает эффективность до 95% — это в 3 раза лучше, чем без LimitRange. Наши клиенты экономят до 40% облачных ресурсов за счёт эффективного распределения квот. Правильно настроенные квоты и лимиты сокращают затраты на инстансы на 30-50%.

Как ResourceQuota и LimitRange решают проблему noisy-neighbor?

ResourceQuota ограничивает суммарное потребление ресурсов в namespace. Kubernetes будет отклонять создание новых Pod, если их добавление нарушит квоту:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-standard
  namespace: tenant-acme
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    pods: "40"
    services.loadbalancers: "2"
    services.nodeports: "0"
    count/deployments.apps: "20"
    count/jobs.batch: "10"
    persistentvolumeclaims: "15"
    requests.storage: "100Gi"
    gold.storageclass.storage.k8s.io/requests.storage: "50Gi"

services.nodeports: "0" — запрет NodePort сервисов для тенантов. Это частая политика безопасности в мультитенантных кластерах.

gold.storageclass.storage.k8s.io/requests.storage: "50Gi" — лимит на конкретный StorageClass. Тенант может использовать дешёвый standard-storage без ограничений (до общего лимита), но дорогого SSD не более 50 Gi.

После создания ResourceQuota Kubernetes требует явных requests и limits в каждом Pod. Если Pod не имеет requests — он не будет создан (must specify requests for cpu). Это неожиданное поведение, которое ломает деплои команд, не привыкших указывать ресурсы. Наш опыт показывает, что это одна из частых проблем при внедрении квот.

Почему LimitRange необходим для работы ResourceQuota?

LimitRange работает на уровне отдельного Pod/Container. Устанавливает:

  • дефолтные requests и limits, если не указаны явно
  • минимальные и максимальные значения
  • максимальное соотношение limit/request (LimitRequestRatio)
apiVersion: v1
kind: LimitRange
metadata:
  name: tenant-limits
  namespace: tenant-acme
spec:
  limits:
    - type: Container
      default:
        cpu: "500m"
        memory: "256Mi"
      defaultRequest:
        cpu: "100m"
        memory: "64Mi"
      max:
        cpu: "2"
        memory: "2Gi"
      min:
        cpu: "50m"
        memory: "32Mi"
    - type: PersistentVolumeClaim
      max:
        storage: "20Gi"
      min:
        storage: "1Gi"

default — если Pod создан без limits, LimitRange подставит их автоматически. Это решает проблему с ResourceQuota, требующей явных лимитов: даже если разработчик забыл написать resources: — Pod создастся с дефолтными значениями из LimitRange.

LimitRequestRatio — ограничение на burst. max.cpu / defaultRequest.cpu здесь равно 20 — контейнер может запрашивать 100m CPU и получать burst до 2000m. Если нужно ограничить burst:

 - type: Container maxLimitRequestRatio: cpu: "4" 

Теперь если request = 100m, limit не может быть больше 400m.

Как настроить ResourceQuota и LimitRange для мультитенантного кластера?

Реальный SaaS обычно имеет несколько планов с разными лимитами. Удобно управлять через кастомный оператор или шаблоны Helm, но структура простая. Сравните планы в таблице:

план CPU request/limit Memory request/limit Pods Storage
Free 0.5 / 1 512Mi / 1Gi 10 10Gi
Starter 2 / 4 2Gi / 4Gi 20 50Gi
Professional 8 / 16 8Gi / 16Gi 60 200Gi
Enterprise без лимита без лимита 200 без лимита

При апгрейде плана — обновляем ResourceQuota и LimitRange в namespace тенанта через Helm upgrade или Kubernetes API.

Пошаговая инструкция внедрения квот

  1. Определите уровни обслуживания и соответствующие лимиты (таблица выше).
  2. Создайте ResourceQuota для каждого namespace с учётом pods и count ресурсов.
  3. Создайте LimitRange, чтобы все Pod имели минимальные requests и явные limits.
  4. Протестируйте: попробуйте создать Pod, превышающий лимиты — он должен быть отклонён.
  5. Настройте мониторинг (kube-state-metrics) и алерт при 80% использования квоты.

Типичные проблемы при внедрении квот

Проблема Причина Решение
Pod не создаётся с ошибкой 'must specify requests' Отсутствуют ресурсы в Pod Установите LimitRange с default requests
Тенант исчерпал квоту CPU Завышенные лимиты приложений Настройте HorizontalPodAutoscaler с использованием CPU
Неожиданные отказы API при деплое ResourceQuota не позволяет создать Pod Добавьте мониторинг и увеличьте квоту по алерту

Действия при исчерпании квоты

Первое — настроить мониторинг использования квот. Ключевые метрики через kube-state-metrics:

# Использование CPU-квоты тенантом
kube_resourcequota{namespace="tenant-acme", resource="requests.cpu", type="used"} / kube_resourcequota{namespace="tenant-acme", resource="requests.cpu", type="hard"}

Алерт при использовании квоты выше 80% — тенант скоро упрётся в лимит, нужно уведомить или предложить апгрейд. В Enterprise плане мы гарантируем, что лимиты не станут проблемой, и предоставляем runbook для оперативного расширения.

API Throttling

Ограничения ресурсов Kubernetes не затрагивают API вашего приложения — это нужно решать отдельно. Для rate limiting используйте Istio EnvoyFilter или Kong/Nginx:

# Istio EnvoyFilter для rate limiting
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: filter-ratelimit
  namespace: tenant-acme
spec:
  workloadSelector:
    labels:
      app: api-gateway
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: SIDECAR_INBOUND
      patch:
        operation: INSERT_BEFORE
        value:
          name: envoy.filters.http.local_ratelimit
          typed_config:
            "@type": type.googleapis.com/udpa.type.v1.TypedStruct
            token_bucket:
              max_tokens: 1000
              tokens_per_fill: 1000
              fill_interval: 60s

Что входит в настройку квот под ключ

Мы предоставляем:

  • Аудит текущей инфраструктуры и выявление noisy-neighbor
  • Проектирование ResourceQuota и LimitRange под ваши планы
  • Реализация с помощью Terraform, Ansible или Helm
  • Настройка мониторинга и алертов по квотам
  • Документация и обучение вашей команды
  • Гарантия стабильной работы — пост-релизная поддержка 2 недели

Ориентировочный срок настройки — от двух до пяти дней в зависимости от сложности. Стоимость рассчитывается после аудита. Для более детального знакомства с ResourceQuota и LimitRange рекомендуем обратиться к официальной документации: Kubernetes Documentation, Resource Quotas.

Если вы хотите избежать проблем с производительностью в мультитенантном кластере, запишитесь на аудит. Наши инженеры помогут настроить идеальную изоляцию. Закажите аудит и настройку квот для вашего мультитенантного кластера — получите консультацию уже сегодня.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1369
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    816
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1142