Appliquer des quotas de ressources aux espaces de noms

KubernetesBeginner
Pratiquer maintenant

Introduction

Le laboratoire précédent portait sur les demandes (requests) et les limites (limits) de ressources au sein de Pods et de déploiements individuels. Un ResourceQuota étend ce concept au niveau de l'espace de noms (namespace). Il permet à une équipe ou à un administrateur de plateforme de définir des limites, telles que le nombre maximal de Pods autorisés, la quantité totale de CPU pouvant être demandée et la limite de mémoire allouable dans un espace de noms donné.

Dans ce laboratoire, vous allez créer un ResourceQuota pour un espace de noms, inspecter ses limites strictes, observer Kubernetes rejeter un Pod qui ne déclare pas les ressources requises, puis exécuter des Pods conformes jusqu'à ce que l'espace de noms atteigne son quota de Pods.

Préparer un espace de noms pour l'exercice sur les quotas

Dans cette étape, vous allez préparer un espace de noms propre pour vous exercer avec les ResourceQuota.

Commencez dans /home/labex/project. Vous y rédigerez les manifestes de quota et de Pod.

mkdir -p /home/labex/project
cd /home/labex/project

Vérifiez que le serveur d'API Kubernetes est accessible. Si la machine virtuelle vient de démarrer et que le nœud n'est pas encore prêt, attendez quelques secondes et relancez la commande.

kubectl get nodes --request-timeout=5s

La sortie attendue inclut :

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Attendez que le Pod de mise en réseau du cluster soit prêt avant de créer des Pods d'application.

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Sortie attendue :

pod/calico-node-... condition met

Créez un espace de noms nommé ckad-prep-quotas :

kubectl create namespace ckad-prep-quotas

Définissez cet espace de noms comme contexte actuel :

kubectl config set-context --current --namespace=ckad-prep-quotas

Confirmez l'espace de noms actuel :

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

Sortie attendue :

ckad-prep-quotas

Créer un ResourceQuota pour l'espace de noms

Dans cette étape, vous allez créer un ResourceQuota qui limite à la fois le nombre d'objets et le total des ressources demandées.

Le quota pods limite le nombre de Pods pouvant exister dans l'espace de noms. Les quotas requests.* et limits.* suivent la somme des demandes et des limites de ressources déclarées par tous les Pods correspondants. Lorsqu'un espace de noms possède des entrées de quota pour les demandes ou les limites de CPU et de mémoire, les nouveaux Pods doivent déclarer ces champs pour que Kubernetes puisse les comptabiliser.

Créez 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

Appliquez le quota :

kubectl apply -f app-resource-quota.yaml

Sortie attendue :

resourcequota/app-resource-quota created

Inspectez le quota. À ce stade, aucun Pod n'est en cours d'exécution dans l'espace de noms, les valeurs utilisées doivent donc être à zéro.

kubectl describe resourcequota app-resource-quota

La sortie attendue inclut :

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

Observer le rejet d'un Pod par le quota

Dans cette étape, vous allez tenter de créer un Pod sans définir de demandes ni de limites de ressources.

Ce Pod est volontairement incomplet. Comme le quota de l'espace de noms suit les demandes et les limites de CPU et de mémoire, Kubernetes ne peut pas admettre un Pod qui omet ces champs. C'est une erreur utile à identifier lors des tâches CKAD : le manifeste peut être un YAML valide, mais l'admission peut le rejeter en raison de la politique de l'espace de noms.

Créez 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

Essayez d'appliquer le manifeste. Le || true à la fin permet à votre shell de continuer après l'erreur attendue afin que vous puissiez inspecter le résultat.

kubectl apply -f no-resources-pod.yaml || true

La sortie attendue inclut :

Error from server (Forbidden): error when creating "no-resources-pod.yaml": pods "no-resources" is forbidden: failed quota

Confirmez que le Pod n'a pas été créé :

kubectl get pod no-resources

La sortie attendue inclut :

Error from server (NotFound): pods "no-resources" not found

Vérifiez que le quota indique toujours zéro Pod utilisé :

kubectl get resourcequota app-resource-quota -o 'jsonpath={.status.used.pods}{"\n"}'

Sortie attendue :

0

Exécuter des Pods conformes jusqu'à saturation du quota

Dans cette étape, vous allez créer des Pods incluant des demandes et des limites de ressources, puis observer le quota de nombre de Pods bloquer un troisième Pod.

Chaque Pod valide ci-dessous demande 100m de CPU et 64Mi de mémoire, et se limite à 200m de CPU et 128Mi de mémoire. Deux Pods de ce type tiennent dans le quota. Un troisième Pod possède des champs de ressources valides, mais l'espace de noms n'en autorise que deux.

Créez 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

Appliquez le manifeste et attendez que les deux Pods soient prêts :

kubectl apply -f quota-workers.yaml
kubectl wait --for=condition=Ready pod/quota-worker-a pod/quota-worker-b --timeout=120s

Sortie attendue :

pod/quota-worker-a created
pod/quota-worker-b created
pod/quota-worker-a condition met
pod/quota-worker-b condition met

Inspectez l'utilisation du quota :

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"}'

Sortie attendue :

2 200m 128Mi 400m 256Mi

Créez un troisième Pod avec des ressources valides :

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

La sortie attendue inclut :

Error from server (Forbidden): error when creating "quota-worker-c.yaml": pods "quota-worker-c" is forbidden: exceeded quota

Résumé

Vous avez créé un ResourceQuota d'espace de noms, inspecté ses limites strictes, observé Kubernetes rejeter un Pod omettant les champs de ressources requis, et exécuté des Pods conformes jusqu'à ce que l'espace de noms atteigne sa limite de nombre de Pods. Cela permet de faire le lien entre les paramètres de ressources des conteneurs individuels et la gouvernance des ressources au niveau de l'espace de noms.