Введение
В предыдущей лабораторной работе мы сосредоточились на запросах (requests) и лимитах (limits) ресурсов внутри отдельных подов и развертываний (Deployments). Объект ResourceQuota переносит эту концепцию на уровень пространства имен (namespace). Он позволяет команде или владельцу платформы устанавливать границы, например, ограничивать количество подов, объем запрашиваемого CPU и объем лимитируемой памяти в одном пространстве имен.
В этой лабораторной работе вы создадите ResourceQuota для пространства имен, изучите его жесткие ограничения, увидите, как Kubernetes отклоняет под, в котором не указаны необходимые ресурсы, а затем запустите соответствующие требованиям поды, пока пространство имен не достигнет квоты по количеству подов.
Подготовка пространства имен для практики квот
На этом этапе вы подготовите чистое пространство имен для практики работы с ResourceQuota.
Начните работу в директории /home/labex/project. В этой директории вы будете создавать манифесты квот и подов.
mkdir -p /home/labex/project
cd /home/labex/project
Проверьте, доступен ли API-сервер Kubernetes. Если виртуальная машина только что запустилась и узел еще не готов, подождите несколько секунд и выполните команду снова.
kubectl get nodes --request-timeout=5s
Ожидаемый вывод:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
Дождитесь готовности пода сетевого плагина кластера, прежде чем создавать поды приложений.
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
Ожидаемый вывод:
pod/calico-node-... condition met
Создайте пространство имен с именем ckad-prep-quotas:
kubectl create namespace ckad-prep-quotas
Установите это пространство имен в качестве текущего контекста:
kubectl config set-context --current --namespace=ckad-prep-quotas
Подтвердите текущее пространство имен:
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
Ожидаемый вывод:
ckad-prep-quotas
Создание ResourceQuota для пространства имен
На этом этапе вы создадите ResourceQuota, которая ограничивает как количество объектов, так и общие запрошенные ресурсы.
Квота pods ограничивает количество подов, которые могут существовать в пространстве имен. Квоты requests.* и limits.* отслеживают сумму запросов и лимитов ресурсов, объявленных всеми соответствующими подами. Когда в пространстве имен установлены квоты на запросы или лимиты CPU и памяти, новые поды обязаны объявлять эти поля, чтобы Kubernetes мог учитывать их.
Создайте файл app-resource-quota.yaml:
cat > app-resource-quota.yaml <<'EOF'
apiVersion: v1
kind: ResourceQuota
metadata:
name: app-resource-quota
spec:
hard:
pods: "2"
requests.cpu: "400m"
requests.memory: 256Mi
limits.cpu: "800m"
limits.memory: 512Mi
EOF
Примените квоту:
kubectl apply -f app-resource-quota.yaml
Ожидаемый вывод:
resourcequota/app-resource-quota created
Проверьте квоту. На данный момент в пространстве имен нет запущенных подов, поэтому используемые значения должны быть равны нулю.
kubectl describe resourcequota app-resource-quota
Ожидаемый вывод:
Name: app-resource-quota
Resource Used Hard
limits.cpu 0 800m
limits.memory 0 512Mi
pods 0 2
requests.cpu 0 400m
requests.memory 0 256Mi
Наблюдение за отклонением пода из-за квоты
На этом этапе вы попытаетесь создать под без указания запросов и лимитов ресурсов.
Этот под намеренно неполный. Поскольку квота пространства имен отслеживает запросы и лимиты CPU и памяти, Kubernetes не может принять под, в котором отсутствуют эти поля. Это полезный сценарий для задач CKAD: манифест может быть валидным YAML, но система допуска (admission) все равно может отклонить его из-за политики пространства имен.
Создайте файл no-resources-pod.yaml:
cat > no-resources-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: no-resources
labels:
app: no-resources
spec:
terminationGracePeriodSeconds: 0
containers:
- name: app
image: busybox:1.36
command:
- /bin/sh
- -c
- 'sleep 3600'
EOF
Попробуйте применить манифест. Конструкция || true в конце позволяет оболочке продолжить работу после ожидаемой ошибки, чтобы вы могли проверить результат.
kubectl apply -f no-resources-pod.yaml || true
Ожидаемый вывод:
Error from server (Forbidden): error when creating "no-resources-pod.yaml": pods "no-resources" is forbidden: failed quota
Убедитесь, что под не был создан:
kubectl get pod no-resources
Ожидаемый вывод:
Error from server (NotFound): pods "no-resources" not found
Проверьте, что квота по-прежнему показывает ноль используемых подов:
kubectl get resourcequota app-resource-quota -o 'jsonpath={.status.used.pods}{"\n"}'
Ожидаемый вывод:
0
Запуск соответствующих требованиям подов до заполнения квоты
На этом этапе вы создадите поды, которые включают запросы и лимиты ресурсов, а затем увидите, как квота на количество подов блокирует создание третьего пода.
Каждый из валидных подов ниже запрашивает 100m CPU и 64Mi памяти, ограничивая себя 200m CPU и 128Mi памяти. Два таких пода укладываются в квоту. Третий под имеет корректные поля ресурсов, но пространство имен разрешает только два пода.
Создайте файл quota-workers.yaml:
cat > quota-workers.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: quota-worker-a
labels:
app: quota-worker
spec:
terminationGracePeriodSeconds: 0
containers:
- name: app
image: busybox:1.36
command: ["/bin/sh", "-c", "echo worker-a-ready; sleep 3600"]
resources:
requests:
cpu: 100m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
---
apiVersion: v1
kind: Pod
metadata:
name: quota-worker-b
labels:
app: quota-worker
spec:
terminationGracePeriodSeconds: 0
containers:
- name: app
image: busybox:1.36
command: ["/bin/sh", "-c", "echo worker-b-ready; sleep 3600"]
resources:
requests:
cpu: 100m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
EOF
Примените манифест и дождитесь готовности обоих подов:
kubectl apply -f quota-workers.yaml
kubectl wait --for=condition=Ready pod/quota-worker-a pod/quota-worker-b --timeout=120s
Ожидаемый вывод:
pod/quota-worker-a created
pod/quota-worker-b created
pod/quota-worker-a condition met
pod/quota-worker-b condition met
Проверьте использование квоты:
kubectl get resourcequota app-resource-quota -o 'jsonpath={.status.used.pods}{" "}{.status.used.requests\.cpu}{" "}{.status.used.requests\.memory}{" "}{.status.used.limits\.cpu}{" "}{.status.used.limits\.memory}{"\n"}'
Ожидаемый вывод:
2 200m 128Mi 400m 256Mi
Создайте третий под с корректными ресурсами:
cat > quota-worker-c.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: quota-worker-c
labels:
app: quota-worker
spec:
terminationGracePeriodSeconds: 0
containers:
- name: app
image: busybox:1.36
command: ["/bin/sh", "-c", "sleep 3600"]
resources:
requests:
cpu: 100m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
EOF
kubectl apply -f quota-worker-c.yaml || true
Ожидаемый вывод:
Error from server (Forbidden): error when creating "quota-worker-c.yaml": pods "quota-worker-c" is forbidden: exceeded quota
Резюме
Вы создали ResourceQuota для пространства имен, изучили его жесткие ограничения, увидели, как Kubernetes отклоняет под, в котором отсутствовали обязательные поля ресурсов, и запускали соответствующие требованиям поды, пока пространство имен не достигло лимита по количеству подов. Это связывает настройки ресурсов отдельных контейнеров с управлением ресурсами на уровне пространства имен.


