Применение квот ресурсов пространства имен

KubernetesBeginner
Практиковаться сейчас

Введение

В предыдущей лабораторной работе мы сосредоточились на запросах (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 отклоняет под, в котором отсутствовали обязательные поля ресурсов, и запускали соответствующие требованиям поды, пока пространство имен не достигло лимита по количеству подов. Это связывает настройки ресурсов отдельных контейнеров с управлением ресурсами на уровне пространства имен.