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

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

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

Зауважимо: коли в мультитенантному кластері один тенант запускає resource-intensive batch job, інші сервіси деградують — ефект noisy-neighbor. Без квот на ресурси ви не контролюєте споживання. У кластері з 30+ тенантами 10% вузлів можуть використовувати 200% CPU під кешами, залишаючи сусідів без процесора. Єдиний спосіб гарантувати стабільність — налаштувати ResourceQuota та LimitRange для кожного namespace. Наші інженери з понад 5-річним досвідом у Kubernetes та 100+ проектами з ізоляції ресурсів роблять це під ключ: від аудиту до моніторингу. Оцінка проекту займає 2 дні, повна реалізація — від 2 до 5 днів. Середня економія після впровадження квот становить 150 000 грн на місяць на кластер із 30 вузлів. Вартість зайвих ресурсів за відсутності квот може сягати 300 000 грн на місяць.

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