Introduction
Le planificateur choisit généralement n’importe quel nœud compatible. Les labels et les affinités expriment les préférences des charges de travail, tandis que les taints permettent aux nœuds de repousser les Pods qui ne disposent pas des tolérances correspondantes.
Vous allez appliquer progressivement ces mécanismes au nœud préparé, puis utiliser les événements des Pods pour distinguer une règle de planification stricte d’une simple préférence.
Gardez à l’esprit le modèle suivant : les labels décrivent les nœuds, les sélecteurs et les affinités expriment ce qu’un Pod recherche, les taints indiquent ce qu’un nœud refuse, et les tolérances permettent à un Pod de passer outre une règle de rejet correspondante. Aucun de ces mécanismes ne « déplace » directement un Pod déjà en cours d’exécution.
Étiqueter le nœud pour contrôler le placement
Dans cette étape, ajoutez des labels descriptifs et affichez-les sous forme de colonnes.
Les labels décrivent volontairement le placement de la charge de travail plutôt que l’identité de l’application. workload-zone=local représente l’emplacement, tandis que disk-class=fast représente une capacité. Kubernetes ne vérifie pas leur signification métier ; ce sont vos règles de planification qui leur donnent un sens.
cd /home/labex/project/pod-scheduling
kubectl create namespace practice-scheduling
kubectl label node labex-v135 workload-zone=local disk-class=fast
kubectl get nodes -L workload-zone,disk-class
Les labels sont des informations utilisées par les sélecteurs et les affinités ; ils ne déplacent pas automatiquement les Pods existants, sauf si un contrôleur crée des remplacements.
L’option -L ajoute une colonne pour chaque clé de label. Voir local et fast sur la ligne du nœud confirme que le planificateur peut évaluer les règles utilisées dans les étapes suivantes.
NAME STATUS ROLES ... VERSION WORKLOAD-ZONE DISK-CLASS
labex-v135 Ready control-plane ... v1.35.5 local fast
Cela confirme également que l’environnement mis à niveau exécute Kubernetes v1.35.5. Les deux colonnes personnalisées proviennent des labels que vous venez d’ajouter.
Exiger un nœud avec nodeSelector
Dans cette étape, créez un Pod avec la règle de placement exacte la plus simple.
nodeSelector est une map de correspondances d’égalité obligatoires. Le Pod est éligible uniquement sur un nœud dont chaque clé possède la valeur demandée. Cette méthode convient à un placement obligatoire et simple.
cd /home/labex/project/pod-scheduling
cat <<'EOF' > selected-pod.yaml
apiVersion: v1
kind: Pod
metadata: {name: selected-pod, namespace: practice-scheduling}
spec:
nodeSelector: {disk-class: fast}
containers:
- {name: worker, image: busybox:1.36, imagePullPolicy: IfNotPresent, command: ["sh", "-c", "while true; do sleep 30; done"]}
EOF
Appliquez le Pod, attendez qu’il soit prêt, puis vérifiez le nœud qui lui a été attribué dans la colonne NODE :
kubectl apply -f selected-pod.yaml
kubectl wait --for=condition=Ready pod/selected-pod -n practice-scheduling --timeout=120s
kubectl get pod selected-pod -n practice-scheduling -o wide
nodeSelector est obligatoire : un Pod reste à l’état Pending lorsqu’aucun nœud ne possède tous les labels demandés.
Le nœud sélectionné devrait être labex-v135. La réussite de la planification prouve que le label disk-class=fast du nœud correspondait à l’exigence du Pod.
pod/selected-pod condition met
NAME READY STATUS ... NODE
selected-pod 1/1 Running ... labex-v135
La colonne NODE indique le résultat de la planification ; le nodeSelector présent dans le manifeste explique pourquoi ce nœud était éligible.
Comparer les affinités requise et préférée
Dans cette étape, créez un Pod qui exige la zone locale et privilégie un disque rapide.
L’affinité de nœud est plus expressive que nodeSelector. La section requise exclut les nœuds qui ne correspondent pas aux critères ; la section préférée attribue un poids aux nœuds correspondants, sans toutefois rendre cette préférence obligatoire.
Les noms de champs longs décrivent le moment d’application de la règle : celle-ci est évaluée pendant la planification, puis ignorée pendant l’exécution. Si un label est modifié ultérieurement, Kubernetes n’expulse pas le Pod en cours d’exécution uniquement à cause de cette règle d’affinité.
cd /home/labex/project/pod-scheduling
cat <<'EOF' > affinity-pod.yaml
apiVersion: v1
kind: Pod
metadata: {name: affinity-pod, namespace: practice-scheduling}
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions: [{key: workload-zone, operator: In, values: [local]}]
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions: [{key: disk-class, operator: In, values: [fast]}]
containers:
- {name: worker, image: busybox:1.36, imagePullPolicy: IfNotPresent, command: ["sh", "-c", "while true; do sleep 30; done"]}
EOF
Appliquez le Pod et attendez sa planification :
kubectl apply -f affinity-pod.yaml
kubectl wait --for=condition=Ready pod/affinity-pod -n practice-scheduling --timeout=120s
kubectl get pod affinity-pod -n practice-scheduling -o wide
Les règles requises filtrent les nœuds compatibles ; les règles préférées attribuent un score aux nœuds restants. IgnoredDuringExecution signifie que les modifications ultérieures des labels n’expulsent pas un Pod déjà en cours d’exécution.
Le tableau obtenu indique à nouveau labex-v135. Dans ce cluster à un seul nœud, la règle requise workload-zone=local détermine la compatibilité ; la règle préférée concernant le disque rapide illustre la syntaxe de pondération sans nécessiter la création d’un second nœud uniquement à des fins de comparaison.
Utiliser un taint et une tolérance
Dans cette étape, appliquez un taint au nœud, observez un Pod sans tolérance rester à l’état Pending, puis créez un Pod autorisé.
Le taint possède la clé practice-reserved, la valeur true et l’effet NoSchedule. Cet effet bloque les nouveaux Pods dépourvus de la tolérance correspondante, mais n’expulse pas les Pods déjà en cours d’exécution sur le nœud.
kubectl taint node NODE key=value:effect associe cette règle à un nœud. La commande kubectl run suivante crée un Pod autonome sans tolérance, et l’attente de sa condition PodScheduled laisse au planificateur dix secondes au maximum pour démontrer l’échec attendu.
cd /home/labex/project/pod-scheduling
kubectl taint node labex-v135 practice-reserved=true:NoSchedule
kubectl run blocked-pod -n practice-scheduling --image=busybox:1.36 --image-pull-policy=IfNotPresent --restart=Never -- sh -c 'sleep 3600'
kubectl wait --for=condition=PodScheduled pod/blocked-pod -n practice-scheduling --timeout=10s || true
kubectl events -n practice-scheduling --for pod/blocked-pod
L’expiration du délai est attendue et || true permet à la leçon de continuer. L’événement de planification devrait mentionner un taint non toléré et expliquer ainsi pourquoi le Pod reste à l’état Pending.
error: timed out waiting for the condition on pods/blocked-pod
LAST SEEN TYPE REASON OBJECT MESSAGE
... Warning FailedScheduling Pod/blocked-pod 0/1 nodes are available: 1 node(s) had untolerated taint(s)...
Ici, l’état Pending est le résultat expérimental attendu. Le planificateur a évalué le Pod, mais n’a trouvé aucun nœud qu’il était autorisé à utiliser.
Créez une tolérance correspondante. Une tolérance permet de planifier le Pod malgré le taint ; elle ne sélectionne pas le nœud à elle seule.
cat <<'EOF' > tolerated-pod.yaml
apiVersion: v1
kind: Pod
metadata: {name: tolerated-pod, namespace: practice-scheduling}
spec:
nodeSelector: {workload-zone: local}
tolerations:
- {key: practice-reserved, operator: Equal, value: "true", effect: NoSchedule}
containers:
- {name: worker, image: busybox:1.36, imagePullPolicy: IfNotPresent, command: ["sh", "-c", "while true; do sleep 30; done"]}
EOF
kubectl apply -f tolerated-pod.yaml
kubectl wait --for=condition=Ready pod/tolerated-pod -n practice-scheduling --timeout=120s
kubectl delete pod blocked-pod -n practice-scheduling
Le Pod tolérant possède également un nodeSelector : une règle sélectionne le nœud et l’autre autorise son admission. La suppression du Pod volontairement bloqué laisse l’espace de noms dans un état propre et sain.
pod/tolerated-pod condition met confirme que l’ajout de la tolérance correspondante a modifié le résultat. Les Pods précédents restent en cours d’exécution, car NoSchedule s’applique aux nouveaux placements et n’expulse pas les Pods déjà actifs.
Résumé
Vous avez utilisé les labels, nodeSelector, les affinités requise et préférée, les événements du planificateur, les taints et les tolérances pour exprimer séparément les intentions de placement et les règles d’admission des nœuds.


