Introduction
Les erreurs de configuration des PriorityClass Kubernetes avec exemples pratiques aident les opérateurs à passer d'un problème observé à un résultat vérifié. Commencez par identifier la version installée, la topologie de déploiement, les prérequis et le composant exact inspecté. Cet article se concentre sur la configuration des PriorityClass Kubernetes pour les développeurs, les consultants DevOps et les équipes techniques de startups. Il relie les erreurs de configuration des PriorityClass, la validation, la restauration et le dépannage à des commandes, des sorties attendues, des signaux d'échec et des décisions de récupération adaptées à la technologie choisie.
L'objectif est la sécurité opérationnelle : observer avant de changer, limiter le rayon d'impact, utiliser des espaces réservés plutôt que des secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.
Inventaire de version et d'environnement
Pour la configuration des PriorityClass Kubernetes, l'inventaire de version et d'environnement doit nommer le composant concerné, la plage de versions prises en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande ou le signal qui vérifie le résultat.
Dans l'inventaire de version et d'environnement, séparez l'observation de l'intervention. Capturez d'abord l'état actuel et les horodatages, protégez les informations d'identification et le matériel privé, puis ne modifiez qu'un seul élément ciblé uniquement lorsque son rayon d'impact et son chemin de récupération sont compris.
Que sont les PriorityClass ?
Les objets PriorityClass sont des ressources non liées à un espace de noms qui attribuent une valeur entière à un nom de priorité. Les pods font référence à une PriorityClass par son nom dans leur champ priorityClassName. Le planificateur utilise cette priorité pour décider quels pods préempter lorsque le cluster manque de capacité, et elle affecte également l'ordre d'admission et d'éviction des pods. Une PriorityClass possède deux champs clés :
value: un entier 32 bits. Plus la valeur est élevée, plus la priorité est haute. Cette valeur doit être inférieure ou égale à 1 000 000 000 (un milliard).globalDefault: un booléen. S'il est défini surtruesur une PriorityClass, elle devient la valeur par défaut pour les pods qui ne spécifient pas depriorityClassName. Une seule PriorityClass peut avoirglobalDefault: true.
De plus, les PriorityClass peuvent avoir un champ preemptionPolicy, défini sur PreemptLowerPriority (par défaut) ou Never. La politique Never empêche les pods avec cette PriorityClass de préempter d'autres pods.
Exemple de manifeste de PriorityClass (high-priority.yaml) :
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000
globalDefault: false
preemptionPolicy: PreemptLowerPriority
description: "Use for critical services that need fast scheduling"
Appliquez-le avec kubectl apply -f high-priority.yaml, puis vérifiez avec kubectl get priorityclass high-priority -o yaml.
Vérification de la version du cluster
Les PriorityClass sont stables dans Kubernetes v1.14 et versions ultérieures. Cependant, certaines fonctionnalités, comme le comportement de préemption par défaut, peuvent différer dans les anciennes versions. Vérifiez toujours la version de votre cluster :
kubectl version --short
La sortie attendue inclut la version du client et du serveur, par exemple :
Client Version: v1.27.2
Kustomize Version: v5.0.1
Server Version: v1.27.2
Si la version du serveur est inférieure à 1.14, la PriorityClass n'est pas disponible en tant qu'API stable (elle était en version bêta depuis la 1.11). Mettez à niveau ou utilisez la version d'API bêta appropriée scheduling.k8s.io/v1beta1 pour les anciens clusters.
Inventaire de l'environnement
Avant de modifier les PriorityClass, rassemblez l'état actuel :
kubectl get priorityclass
kubectl get nodes -o wide
kubectl get pods -A -o wide --field-selector=status.phase=Running
Enregistrez la sortie avec un horodatage pour une comparaison ultérieure :
date > pre-change-state.txt
kubectl get priorityclass -o yaml >> pre-change-state.txt
kubectl get nodes -o wide >> pre-change-state.txt
Cette observation en lecture seule forme un instantané pour le dépannage et la restauration.
Prérequis
- Un cluster Kubernetes en cours d'exécution (v1.14+ recommandée).
kubectlconfiguré avec les autorisations RBAC appropriées. Vous avez besoin des autorisationscreate,update,deletesurpriorityclasses.scheduling.k8s.ioetpodssi vous prévoyez de tester le comportement des pods.- Au moins deux espaces de noms ou deux pods par défaut pour tester la préemption en toute sécurité.
Vérifiez les autorisations avec :
kubectl auth can-i create priorityclasses
kubectl auth can-i delete priorityclasses
Sortie attendue : yes pour les deux si les autorisations sont suffisantes.
Rayon d'impact et chemin de récupération
Modifier ou supprimer une PriorityClass peut provoquer une préemption ou une éviction immédiate des pods qui y font référence. Comprenez toujours quels pods utilisent une PriorityClass avant de la modifier :
kubectl get pods -A -o json | jq -r '.items[] | select(.spec.priorityClassName != null) | "\(.metadata.namespace)/\(.metadata.name): \(.spec.priorityClassName)"'
Cela liste tous les pods avec une classe de priorité. Si une PriorityClass est supprimée alors que des pods y font encore référence, ces pods ne peuvent pas être planifiés jusqu'à ce que la PriorityClass soit recréée ou que le pod soit mis à jour. Pour récupérer, recréez la PriorityClass avec le même nom et la même valeur.
Vérification pratique de Kubernetes pour l'inventaire de version et d'environnement : commencez par kubectl get pods -o wide, puis utilisez kubectl describe pod <name> pour les détails de planification et d'événements, kubectl logs <name> --previous pour les boucles de crash, et kubectl rollout status deployment/<name> avant de supposer qu'une version a réussi.
Gardez le test local petit. Appliquez un manifeste, inspectez les ressources générées et vérifiez le trafic avec kubectl port-forward ou un type de service local avant de passer à un équilibreur de charge cloud ou à un contrôleur Ingress.
Chemin de configuration sûr
Pour la configuration des PriorityClass Kubernetes, le chemin de configuration sûr doit nommer le composant concerné, la plage de versions prises en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande ou le signal qui vérifie le résultat.
Dans le chemin de configuration sûr, séparez l'observation de l'intervention. Capturez d'abord l'état actuel et les horodatages, protégez les informations d'identification et le matériel privé, puis ne modifiez qu'un seul élément ciblé uniquement lorsque son rayon d'impact et son chemin de récupération sont compris.
Étape 1 : Définir des niveaux de priorité clairs
Une erreur courante est de créer trop de PriorityClass avec des valeurs arbitraires, ce qui conduit à une préemption imprévisible. Définissez plutôt un petit ensemble de niveaux :
| Nom de la PriorityClass | Valeur | Utilisation prévue |
|---|---|---|
system-cluster-critical | 2000000000 (intégrée, non définie par l'utilisateur) | Pods système Kubernetes |
high-priority | 1000 | Microservices critiques en production |
medium-priority | 100 | Charges de travail normales |
low-priority | 10 | Tâches par lots, pods de développement |
Gardez les valeurs séparées par au moins un facteur 10 pour permettre des insertions futures. Documentez chaque classe dans un manifeste versionné.
Exemple medium-priority.yaml :
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: medium-priority
value: 100
globalDefault: true
description: "Default priority class for all namespaces"
Définir globalDefault: true sur medium-priority signifie que les pods sans priorityClassName obtiennent la valeur 100. Remarque : une seule PriorityClass peut avoir globalDefault: true. Pour changer la valeur par défaut, définissez globalDefault: false sur la classe par défaut actuelle avant d'appliquer une nouvelle.
Étape 2 : Appliquer les modifications de manière contrôlée
Appliquez toujours les modifications de manière ciblée et réversible :
- Faites une sauvegarde de la PriorityClass actuelle :
kubectl get priorityclass high-priority -o yaml > high-priority-backup.yaml
- Appliquez le manifeste modifié :
kubectl apply -f high-priority.yaml
- Observez le résultat :
kubectl get priorityclass high-priority -o yaml
La sortie attendue inclut le nouveau champ value. Si l'application échoue, vérifiez les erreurs de validation telles qu'une valeur hors plage ou un globalDefault en double.
Étape 3 : Tester avec un pod canari
Avant d'attribuer une nouvelle PriorityClass à des pods de production, testez avec un pod canari dans un espace de noms séparé :
# canary-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: canary-high
namespace: test
spec:
priorityClassName: high-priority
containers:
- name: nginx
image: nginx:1.21
resources:
requests:
cpu: "50m"
memory: "64Mi"
Appliquez et vérifiez :
kubectl apply -f canary-pod.yaml
kubectl get pod canary-high -n test -o yaml | grep priorityClassName
Sortie attendue :
priorityClassName: high-priority
Si le pod est en Pending, la PriorityClass peut ne pas exister ou le pod peut manquer de ressources suffisantes.
Étape 4 : Vérifier le comportement de préemption
Pour vérifier la préemption, créez deux pods : un à faible priorité et un à haute priorité, avec une capacité de nœud limitée. Par exemple, si un nœud a 1 CPU et que le pod à faible priorité demande 0,9 CPU, l'application d'un pod à haute priorité demandant 0,5 CPU devrait préempter le pod à faible priorité.
Voici une séquence pratique :
- Créez un pod à faible priorité qui demande la plupart des ressources du nœud :
# low-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: low-pod
spec:
priorityClassName: low-priority
containers:
- name: busybox
image: busybox
command: ["sleep", "3600"]
resources:
requests:
cpu: "900m"
memory: "100Mi"
- Appliquez-le et attendez qu'il soit
Running. Créez ensuite un pod à haute priorité :
# high-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: high-pod
spec:
priorityClassName: high-priority
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "500m"
memory: "100Mi"
- Appliquez le pod à haute priorité et observez :
kubectl apply -f high-pod.yaml
kubectl get pods -w
Attendu : low-pod est préempté (statut Terminating), et high-pod devient Running. Cela vérifie que les valeurs de priorité fonctionnent comme prévu.
Si le pod à faible priorité n'est pas préempté, vérifiez que les valeurs de PriorityClass sont correctes, que la preemptionPolicy sur la classe à haute priorité n'est pas Never, et que le planificateur a la porte de fonctionnalité PodPriority activée (uniquement pour les anciens clusters).
Gardez le test local petit. La préemption peut perturber l'état du cluster, donc testez dans un espace de noms dédié ou sur un cluster non productif d'abord.
Vérification et diagnostics
Pour la configuration des PriorityClass Kubernetes, la vérification et les diagnostics doivent nommer le composant concerné, la plage de versions prises en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande ou le signal qui vérifie le résultat.
Dans la vérification et les diagnostics, séparez l'observation de l'intervention. Capturez d'abord l'état actuel et les horodatages, protégez les informations d'identification et le matériel privé, puis ne modifiez qu'un seul élément ciblé uniquement lorsque son rayon d'impact et son chemin de récupération sont compris.
Diagnostiquer les problèmes de PriorityClass
Symptômes courants et leurs causes :
| Symptôme | Cause probable | Commande de diagnostic |
|---|---|---|
Pod bloqué en Pending avec l'événement "no PriorityClass with name X found" | PriorityClass supprimée ou renommée | kubectl describe pod <pod-name> |
| Pod préempté de manière inattendue | Un pod à haute priorité a été planifié, le pod à faible priorité avait une priorité inférieure | kubectl get events --sort-by='.lastTimestamp' |
| Le pod à haute priorité ne peut pas préempter | preemptionPolicy: Never sur sa PriorityClass | kubectl get priorityclass <name> -o yaml |
| Le pod obtient la priorité par défaut 0 | Aucun globalDefault défini, le pod n'a pas de priorityClassName | kubectl get pod <pod-name> -o yaml | grep priorityClassName |
Exemple : Pour voir pourquoi un pod est en attente, utilisez :
kubectl describe pod high-pod -n test
Regardez sous Events :
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 2m default-scheduler 0/1 nodes are available: 1 Insufficient cpu, 1 node(s) didn't match Pod's node affinity/selector.
Si l'événement mentionne "no PriorityClass with name", la PriorityClass est manquante.
Valider les objets PriorityClass
Utilisez kubectl apply --dry-run=client pour valider la syntaxe sans modifier le cluster :
kubectl apply -f high-priority.yaml --dry-run=client
Sortie attendue :
priorityclass.scheduling.k8s.io/high-priority created (dry run)
Pour une validation plus approfondie, utilisez kubectl apply --dry-run=server (disponible dans Kubernetes 1.18+) :
kubectl apply -f high-priority.yaml --dry-run=server
S'il y a une erreur de validation, comme une valeur dépassant 1 000 000 000, le serveur renvoie une erreur comme :
The PriorityClass "high-priority" is invalid: value: Invalid value: 2000000000: must be less than or equal to 1000000000
Auditer les priorités des pods
Listez tous les pods avec leurs valeurs de priorité :
kubectl get pods -A -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name,PRIORITY:.spec.priority,PRIORITY_CLASS:.spec.priorityClassName
Exemple de sortie :
NAMESPACE NAME PRIORITY PRIORITY_CLASS
default frontend 0 <none>
kube-system coredns-... 2000000000 system-cluster-critical
Remarque : Les pods sans classe de priorité affichent la priorité 0 et <none>.
Commandes de diagnostic
kubectl get events -A --sort-by='.lastTimestamp'pour voir les événements de préemption récents.kubectl logs <pod-name> --previouspour vérifier les boucles de crash non liées à la priorité.kubectl rollout status deployment/<name>pour vérifier un déploiement qui inclut des changements de classe de priorité.
Comparez toujours ces diagnostics avec l'état pré-changement capturé précédemment.
Modes de défaillance et récupération
Pour la configuration des PriorityClass Kubernetes, les modes de défaillance et la récupération doivent nommer le composant concerné, la plage de versions prises en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande ou le signal qui vérifie le résultat.
Dans les modes de défaillance et la récupération, séparez l'observation de l'intervention. Capturez d'abord l'état actuel et les horodatages, protégez les informations d'identification et le matériel privé, puis ne modifiez qu'un seul élément ciblé uniquement lorsque son rayon d'impact et son chemin de récupération sont compris.
Mode de défaillance 1 : Supprimer une PriorityClass en cours d'utilisation
Si vous supprimez une PriorityClass qui est encore référencée par des pods, ces pods ne peuvent pas être planifiés (nouveaux pods) et peuvent être évincés si le kubelet est redémarré. Pour récupérer :
- Recréez la PriorityClass à partir de la sauvegarde ou de mémoire :
kubectl create -f high-priority-backup.yaml
- Vérifiez qu'elle est restaurée :
kubectl get priorityclass high-priority
- Vérifiez s'il reste des pods en état d'erreur :
kubectl get pods -A | grep -v Running | grep -v Completed
Mode de défaillance 2 : Définir accidentellement une PriorityClass comme globalDefault
Si vous définissez globalDefault: true sur une classe à haute priorité, tous les nouveaux pods sans priorityClassName hériteront de cette haute priorité, ce qui peut entraîner une préemption inattendue de charges de travail importantes. Pour récupérer :
kubectl patch priorityclass high-priority -p '{"globalDefault":false}'
Ensuite, assurez-vous qu'une classe de priorité inférieure (ou aucune) est la valeur par défaut. Si vous aviez une valeur par défaut précédente, rétablissez-la :
kubectl patch priorityclass medium-priority -p '{"globalDefault":true}'
Vérifiez :
kubectl get priorityclass -o custom-columns=NAME:.metadata.name,VALUE:.value,GLOBAL_DEFAULT:.globalDefault
Mode de défaillance 3 : La préemption provoque une panne d'application
Si un pod à haute priorité préempte des pods critiques à faible priorité, le cluster peut connaître une augmentation des redémarrages de pods. Pour atténuer :
- Identifiez quels pods ont été préemptés en vérifiant les événements :
kubectl get events -A | grep Preempted
Exemple d'événement :
5m Warning Preempted pod/low-pod Preempted by pod/high-pod on node node1
- Si la préemption n'était pas intentionnelle, ajustez la politique de préemption sur la classe à haute priorité :
kubectl patch priorityclass high-priority -p '{"preemptionPolicy":"Never"}'
Remarque : Cela empêche tous les pods utilisant cette classe de préempter les autres ; ils attendront les ressources à la place.
- Alternativement, abaissez la valeur de priorité de la classe fautive :
kubectl patch priorityclass high-priority -p '{"value":50}'
Mode de défaillance 4 : Faute de frappe dans le nom de la PriorityClass
Une erreur courante est une faute de frappe dans le priorityClassName dans la spécification d'un pod. Le pod ne sera pas planifié si la classe n'existe pas. Diagnostiquez :
kubectl describe pod <pod-name> | grep -A5 Events
Cherchez :
Warning FailedScheduling 2m default-scheduler 0/1 nodes are available: 1 no PriorityClass with name high-priorty found.
Corrigez en modifiant la spécification du pod ou en créant la PriorityClass avec le nom attendu.
Liste de contrôle de récupération
- Gardez toujours des sauvegardes des YAML de PriorityClass dans le contrôle de version.
- Avant de supprimer, exécutez
kubectl get pods -A -o json | jq '.items[] | select(.spec.priorityClassName=="<name>")'pour voir les pods affectés. - Utilisez
kubectl applyavec--dry-run=serverpour détecter les erreurs. - Ayez un plan de restauration : réappliquez le manifeste de la PriorityClass précédente.
Liste de contrôle opérationnelle
Pour la configuration des PriorityClass Kubernetes, la liste de contrôle opérationnelle doit nommer le composant concerné, la plage de versions prises en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande ou le signal qui vérifie le résultat.
Dans la liste de contrôle opérationnelle, séparez l'observation de l'intervention. Capturez d'abord l'état actuel et les horodatages, protégez les informations d'identification et le matériel privé, puis ne modifiez qu'un seul élément ciblé uniquement lorsque son rayon d'impact et son chemin de récupération sont compris.
Liste de contrôle pré-changement
- [ ] Vérifiez la version du cluster :
kubectl version --short, vérifiez que le serveur >= v1.14. - [ ] Listez les PriorityClass existantes :
kubectl get priorityclass -o wide. - [ ] Identifiez les pods utilisant chaque PriorityClass :
kubectl get pods -A -o json | jq '.items[] | select(.spec.priorityClassName != null) | "\(.metadata.namespace)/\(.metadata.name): \(.spec.priorityClassName)"'. - [ ] Capturez l'état actuel dans un fichier :
kubectl get priorityclass -o yaml > priorityclass-snapshot-$(date +%Y%m%d).yaml. - [ ] Validez les autorisations RBAC :
kubectl auth can-i update priorityclasses. - [ ] Préparez le manifeste de restauration pour la PriorityClass cible.
Liste de contrôle d'exécution du changement
- [ ] Appliquez le changement avec
kubectl apply -f <file>.yaml --dry-run=serverd'abord pour détecter les erreurs de validation. - [ ] Si le dry-run réussit, appliquez réellement :
kubectl apply -f <file>.yaml. - [ ] Vérifiez immédiatement l'objet :
kubectl get priorityclass <name> -o yamlet vérifiezvalue,globalDefault,preemptionPolicy. - [ ] Pour les changements de pods, appliquez un pod à la fois et observez avec
kubectl get pods -o wide. - [ ] Vérifiez les événements du planificateur :
kubectl get events --sort-by='.lastTimestamp' | grep -i preempt.
Liste de contrôle de vérification post-changement
- [ ] Confirmez que les pods attendus sont en cours d'exécution et à la bonne priorité :
kubectl get pods -o custom-columns=POD:.metadata.name,PRIORITY:.spec.priority,PRIORITY_CLASS:.spec.priorityClassName. - [ ] Surveillez les préemptions non intentionnelles pendant au moins 10 minutes.
- [ ] En cas de problème, revenez en arrière en utilisant le manifeste de sauvegarde.
- [ ] Documentez le changement et le résultat dans votre journal d'exploitation.
Pièges courants et comment les éviter
- Trop de PriorityClass : Gardez le nombre petit (3-5). Utilisez
kubectl get priorityclasspour réviser. - Aucun
globalDefaultdéfini : Les pods sans classe de priorité obtiennent la valeur 0. Décidez si vous voulez une valeur par défaut. - Ignorer la politique de préemption : Si vous ne voulez jamais qu'une classe préempte, définissez
preemptionPolicy: Never. - Modifier les valeurs sur des clusters en direct : Cela peut provoquer une préemption immédiate ; traitez comme un changement avec un plan de restauration.
Implémentez cette liste de contrôle comme un hook de pré-commit ou une étape CI si les PriorityClass sont gérées via GitOps.
Conclusion
Les erreurs de configuration des PriorityClass Kubernetes avec exemples pratiques ne sont utiles que si chaque recommandation est versionnée, observable et réversible lorsque la technologie le permet. Copier une commande sans vérifier les prérequis et la sortie attendue n'est pas une procédure d'exploitation.
Comme prochaine étape, choisissez une vérification à faible risque pour la configuration des PriorityClass Kubernetes : enregistrez l'état actuel, exécutez la vérification documentée, comparez le résultat avec le signal attendu et examinez les dépendances telles que Pod, Node et Resource Quota (qui peuvent également affecter la planification et la préemption).
Un flux de travail technique fiable rend les défaillances visibles, protège les valeurs sensibles, limite les changements à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision.