Введение / Зачем это нужно
Resource Quota — это механизм Kubernetes, который ограничивает суммарное потребление вычислительных ресурсов (CPU, память) и количество объектов (поды, сервисы, PersistentVolumeClaims) в рамках одного namespace. Это критически важно в мультитенантных средах, где несколько команд или проектов используют общий кластер. Без квот один "прожорливый" проект может исчерпать все ресурсы кластера, что приведёт к сбоям в работе других приложений. С помощью ResourceQuota администратор кластера может гарантировать справедливое распределение и предотвратить "шумные соседи".
Требования / Подготовка
- Доступ к кластеру Kubernetes: У вас должен быть настроенный
kubectlс правами на создание ресурсов в целевом namespace (обычно требуются праваadminилиedit). - Существующий namespace: Если тестового namespace нет, создайте его:
kubectl create namespace test-quota - Понимание базовых концепций: Знание о запросах (
requests) и лимитах (limits) для контейнеров, а также о таких ресурсах, какpods,services,persistentvolumeclaims.
Пошаговая инструкция
Шаг 1: Определение политики квоты
Прежде чем писать манифест, решите, какие именно ресурсы и в каком объёме нужно ограничить. Типичные параметры для hard (жёсткий лимит) в ResourceQuota:
requests.cpu— Суммарные запросы на CPU для всех подов в namespace.requests.memory— Суммарные запросы на память.limits.cpu— Суммарные лимиты на CPU.limits.memory— Суммарные лимиты на память.count.pods— Максимальное количество подов.count.services— Максимальное количество сервисов.count.persistentvolumeclaims— Количество PVC.
Пример политики: Для тестового namespace test-quota установим:
- Запросы CPU: 2 ядра (
2) - Запросы памяти: 4 ГиБ (
4Gi) - Лимиты CPU: 4 ядра (
4) - Лимиты памяти: 8 ГиБ (
8Gi) - Количество подов: 10
Шаг 2: Создание манифеста ResourceQuota
Создайте файл quota.yaml со следующим содержимым:
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources-quota
namespace: test-quota # Укажите ваш namespace
spec:
hard:
requests.cpu: "2"
requests.memory: 4Gi
limits.cpu: "4"
limits.memory: 8Gi
count.pods: "10"
# count.services: "5" # Можно раскомментировать для ограничения сервисов
# count.persistentvolumeclaims: "4" # Или PVC
Важно:
- Значения для CPU можно указывать в
m(миллиядрах, например500m= 0.5 ядра) или в целых числах. - Значения для памяти используют суффиксы
Ki,Mi,Gi(кратные 1024) илиK,M,G(кратные 1000). РекомендуетсяGi/Mi. - Поля
count.*принимают целые числа.
Шаг 3: Применение квоты к namespace
Примените созданный манифест:
kubectl apply -f quota.yaml
Вы должны увидеть подтверждение:
resourcequota/compute-resources-quota created
Шаг 4: Проверка состояния квоты
Чтобы убедиться, что квота активна и посмотреть текущее использование ресурсов, выполните:
kubectl describe quota compute-resources-quota -n test-quota
В выводе вы увидите две таблицы: Hard (установленные лимиты) и Used (текущее потребление). Пока что Used будет 0 / <value> для каждого ресурса.
Name: compute-resources-quota
Namespace: test-quota
Resource Used Hard
-------- ---- ----
limits.cpu 0 4
limits.memory 0 8Gi
requests.cpu 0 2
requests.memory 0 4Gi
count.pods 0 10
Шаг 5: Тестирование работы квоты
Теперь попробуйте создать ресурс, который проверит работу квоты. Создайте простой под с явными запросами и лимитами.
- Создайте файл
test-pod.yaml:apiVersion: v1 kind: Pod metadata: name: quota-test-pod namespace: test-quota spec: containers: - name: nginx image: nginx:latest resources: requests: cpu: "500m" # 0.5 ядра memory: "1Gi" limits: cpu: "1" # 1 ядро memory: "2Gi"
Этот под запрашивает 0.5 CPU и 1Gi памяти, что вписывается в наши лимиты (requests.cpu: 2,requests.memory: 4Gi). - Создайте под:
kubectl apply -f test-pod.yaml
Под должен успешно создаться. - Проверьте обновлённую квоту:
kubectl describe quota compute-resources-quota -n test-quota
Теперь в колонкеUsedпоявятся значения, соответствующие запросам созданного пода (0.5 CPU, 1Gi памяти). - Попробуйте превысить квоту. Создайте ещё один под, который запросит, например,
2Giпамяти. После применения второго пода, суммарныеrequests.memoryстанут3Gi. Попробуйте создать третий под с запросом2Giпамяти. Операция провалится с ошибкой, похожей на:Error from server (Forbidden): error when creating "pod2.yaml": ... "exceeded quota: compute-resources-quota, requested: requests.memory=2Gi, used: requests.memory=3Gi, limited: requests.memory=4Gi"
Это доказывает, что квота работает.
Проверка результата
- Основная проверка: Вы успешно создали
ResourceQuotaи наблюдаете за ростом поляUsedпри создании новых ресурсов (подов, PVC). - Проверка на превышение: Попытка создать ресурс, который приведёт к превышению любого из
hard-лимитов, завершается с ошибкойexceeded quota. - Команда статуса:
kubectl get quota -n <namespace>показывает имя квоты и еёHardлимиты.kubectl describe quota— детализированное использование.
Возможные проблемы
- Ошибка
exceeded quotaпри создании подa, который, кажется, вписывается в лимиты.- Причина: ResourceQuota суммирует запросы (
requests) всех подов в namespace. Убедитесь, что суммаrequests.cpuиrequests.memoryвсех существующих подов плюс запросы нового пода не превысятhard-значения. Проверьте текущее использование черезkubectl describe quota. - Решение: Либо увеличьте значения в
ResourceQuota, либо уменьшитеrequestsв манифесте нового пода.
- Причина: ResourceQuota суммирует запросы (
- Квота не применяется к уже запущенным подам.
- Причина: Это ожидаемое поведение. ResourceQuota проверяет запросы на создание новых объектов. Уже работающие поды не затрагиваются.
- Решение: Чтобы включить существующие поды в учёт, необходимо либо вручную удалить и пересоздать их с корректными
requests, либо увеличить квоту до уровня, который покрывает и существующие, и будущие запросы.
- Ошибка при создании ResourceQuota:
unable to recognize "...": no matches for kind "ResourceQuota" in version "v1".- Причина: Обычно указывает на устаревший кластер. В очень старых версиях Kubernetes (до 1.8) ResourceQuota мог быть в
extensions/v1beta1. - Решение: Обновите кластер или используйте корректную apiVersion (
v1для Kubernetes 1.8+). Проверьте версию кластера:kubectl version --short.
- Причина: Обычно указывает на устаревший кластер. В очень старых версиях Kubernetes (до 1.8) ResourceQuota мог быть в
- Неясно, какой именно ресурс исчерпан.
- Причина: Сообщение об ошибке
exceeded quotaобычно содержит имя квоты и конкретный ресурс, который превышен (например,requests.memory). - Решение: Всегда смотрите на имя квоты в ошибке и проверяйте её описание (
kubectl describe quota <name>) для сравненияUsedvsHard.
- Причина: Сообщение об ошибке