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.


