Introduction
La classe de priorité Kubernetes (PriorityClass) est un mécanisme essentiel pour contrôler l'ordonnancement et la préemption des pods dans les clusters de production. Lorsque les ressources sont limitées, le planificateur utilise les priorités pour décider quels pods programmer en premier et quels pods de priorité inférieure peuvent être évincés pour libérer de la place. Une mauvaise configuration des priorités peut entraîner l'éviction inattendue de charges de travail critiques ou la privation de ressources pour des charges moins importantes. Cet article propose une exploration approfondie des concepts avancés de la classe de priorité, avec des conseils pratiques destinés aux développeurs, consultants DevOps et équipes techniques de startups. Nous couvrirons le fonctionnement interne, l'architecture, la configuration, la vérification, les modes de défaillance et la récupération, avec des commandes et des exemples concrets. Vous apprendrez à observer avant de modifier, à limiter le rayon d'impact, à vérifier les résultats et à documenter les procédures de récupération.
Inventaire de l'environnement et des versions
Avant de travailler avec les classes de priorité, établissez une vision claire de votre environnement de cluster. Vérifiez la version de Kubernetes et assurez-vous de disposer des autorisations nécessaires. Les classes de priorité sont des ressources à l'échelle du cluster, vous aurez donc besoin de droits d'administrateur de cluster (cluster-admin) ou équivalents pour les créer ou les modifier.
Vérifiez la version de votre cluster :
kubectl version --short
Le résultat attendu inclut les versions client et serveur, par exemple :
Client Version: v1.27.3
Server Version: v1.27.3
La classe de priorité est disponible depuis Kubernetes 1.11 et stable depuis la version 1.14. Vérifiez que la ressource API existe :
kubectl api-resources | grep priorityclass
Le résultat doit afficher :
priorityclasses pc scheduling.k8s.io/v1 false PriorityClass
Pour une observation en lecture seule, listez les classes de priorité existantes :
kubectl get priorityclass
Exemple de résultat :
NAME VALUE GLOBAL-DEFAULT AGE
system-cluster-critical 2000000000 false 30d
system-node-critical 2000001000 false 30d
default 0 false 30d
high-priority 1000 false 2d
Notez que la classe default avec la valeur 0 est appliquée aux pods sans priorityClassName si elle est définie comme valeur globale par défaut (Kubernetes ne crée pas de classe de priorité par défaut automatiquement ; vous devez la créer).
Procédez par petits changements : commencez par créer une classe de priorité de test avec une valeur modeste, appliquez-la à un pod de test et observez le comportement de l'ordonnancement avant de modifier les charges de travail en production.
Chemin de configuration sécurisé
La classe de priorité est définie par un simple manifeste YAML. Voici un exemple de classe de priorité moyenne :
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: medium-priority
value: 1000
globalDefault: false
description: "Priorité moyenne pour les charges de travail standard"
Appliquez-la :
kubectl apply -f medium-priority.yaml
Résultat attendu :
priorityclass.scheduling.k8s.io/medium-priority created
Champs clés :
value: un entier de 1 à 1 000 000 000. Plus la valeur est élevée, plus la priorité est haute. Les valeurs supérieures à 1 000 000 000 sont réservées aux composants critiques du système.globalDefault: si vrai, cette classe de priorité est utilisée pour les pods qui ne spécifient pas depriorityClassName. Une seule classe de priorité peut avoir ce champ à vrai.description: explication optionnelle lisible par l'humain.
Une fois la classe de priorité créée, assignez-la à un pod :
apiVersion: v1
kind: Pod
metadata:
name: test-priority-pod
spec:
containers:
- name: nginx
image: nginx
priorityClassName: medium-priority
Déployez et observez :
kubectl apply -f test-priority-pod.yaml
kubectl get pod test-priority-pod -o yaml | grep -A2 priority
Le résultat attendu inclut :
priority: 1000
priorityClassName: medium-priority
La préemption se produit lorsqu'un pod de haute priorité ne peut pas être planifié en raison de contraintes de ressources et que le planificateur évince des pods de priorité inférieure. Cela peut entraîner des perturbations si des pods critiques se voient attribuer des priorités inférieures. Testez toujours d'abord dans un espace de noms non destiné à la production.
Vérification et diagnostic
Après avoir appliqué une classe de priorité et l'avoir assignée à des pods, vérifiez que le planificateur respecte la priorité. Utilisez kubectl describe pour inspecter les événements du pod et les décisions d'ordonnancement.
Créez deux classes de priorité : high-priority (valeur 10000) et low-priority (valeur 100). Déployez des pods avec chacune d'elles, puis créez intentionnellement une pression sur les ressources. Par exemple, utilisez un pod gourmand en ressources avec une priorité élevée et observez si les pods de priorité inférieure sont évincés.
Tout d'abord, listez les pods avec leurs priorités :
kubectl get pods -o custom-columns=NAME:.metadata.name,PRIORITY:.spec.priority,CLASS:.spec.priorityClassName,STATUS:.status.phase,NODE:.spec.nodeName
Exemple de résultat :
NAME PRIORITY CLASS STATUS NODE
critical-app 10000 high-priority Running node-1
batch-job 100 low-priority Pending
Si le pod de haute priorité est en attente en raison de ressources insuffisantes, le planificateur peut évincer des pods de priorité inférieure. Vérifiez les événements :
kubectl describe pod critical-app | tail -20
Recherchez des messages tels que :
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 3s default-scheduler 0/3 nodes are available: 1 Insufficient cpu, 2 Insufficient memory.
Normal Preempted 2s default-scheduler Preempted pod batch-job to make room for critical-app
L'événement Preempted indique une préemption réussie. Notez que la préemption ne se produit que si la priorité du pod en attente est supérieure à celle des pods en cours d'exécution et que les pods évincés ont une priorité inférieure et ne sont pas protégés par un PodDisruptionBudget ou d'autres contraintes.
Diagnostiquez les problèmes de priorité : si un pod de haute priorité reste en attente, assurez-vous que la classe de priorité existe et que le priorityClassName du pod correspond. Utilisez kubectl get priorityclass pour confirmer.
Modes de défaillance et récupération
Les modes de défaillance courants incluent :
- Classe de priorité manquante : la spécification du pod fait référence à une classe de priorité inexistante. Le pod échouera à l'admission avec une erreur similaire à :
Error from server (NotFound): priorityclasses.scheduling.k8s.io "high-priority" not found
Récupération : créez la classe de priorité ou corrigez la spécification du pod.
- Valeur invalide : la valeur de la classe de priorité est en dehors de la plage autorisée ou n'est pas un entier. Le serveur d'API la rejette :
The PriorityClass "invalid-pc" is invalid: value: Invalid value: 0: must be greater than 0
Récupération : corrigez la valeur et réappliquez.
- Conflit de valeur par défaut globale : tenter de définir
globalDefault: truesur plus d'une classe de priorité entraîne une erreur. Le serveur d'API garantit qu'une seule valeur par défaut globale existe. - Préemption inattendue : si des pods critiques sont évincés parce qu'ils ont une priorité trop basse, augmentez la valeur de leur classe de priorité ou attribuez-leur une classe de priorité supérieure. Inversement, si des charges de travail de faible priorité sont privées de ressources, envisagez de réduire la priorité du pod préempteur ou d'utiliser des quotas de ressources pour limiter le nombre de pods de haute priorité.
- Pod bloqué en attente : même avec une priorité élevée, un pod peut ne pas être planifié si les ressources des nœuds sont complètement épuisées et que la préemption est désactivée (par exemple, lorsque les pods ont
preemptionPolicy: Never). Vérifiez la politique de préemption du pod :
kubectl get pod <pod-name> -o jsonpath='{.spec.preemptionPolicy}'
La valeur par défaut est PreemptLowerPriority. Si elle est définie sur Never, le pod ne préemptera pas les autres.
Étapes de récupération :
- Identifiez le problème via
kubectl describe pod <nom>etkubectl get events --sort-by=.metadata.creationTimestamp. - Si la classe de priorité est manquante ou mal configurée, corrigez-la et appliquez-la.
- Si la préemption a causé une perturbation, ajustez les priorités ou ajoutez des PodDisruptionBudgets pour protéger les pods critiques.
- Surveillez les événements et les journaux du cluster pour confirmer la récupération.
Conservez toujours une sauvegarde des manifestes des classes de priorité. Utilisez un contrôle de version pour les configurations du cluster.
Liste de contrôle des opérations
Utilisez la liste de contrôle suivante pour garantir des opérations sûres avec les classes de priorité.
Avant le changement
- [ ] Enregistrez les classes de priorité actuelles :
kubectl get priorityclass -o yaml > priorityclasses-backup.yaml - [ ] Identifiez les pods affectés :
kubectl get pods --all-namespaces -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name,PRIORITY:.spec.priority,CLASS:.spec.priorityClassNameet enregistrez le résultat. - [ ] Confirmez la version du cluster et la compatibilité de l'API.
- [ ] Examinez les quotas de ressources et la capacité des nœuds.
Pendant le changement
- [ ] Appliquez le nouveau manifeste de classe de priorité :
kubectl apply -f high-priority.yaml - [ ] Surveillez immédiatement les erreurs :
kubectl get priorityclass high-priority -o yaml - [ ] Déployez un pod de test avec la nouvelle classe :
kubectl apply -f test-high-priority-pod.yaml - [ ] Observez l'ordonnancement :
kubectl get pod test-high-priority -w
Après le changement / Vérification
- [ ] Vérifiez que le pod a la bonne priorité :
kubectl get pod test-high-priority -o jsonpath='{.spec.priority}'résultat attendu : 10000 - [ ] Vérifiez les événements de préemption :
kubectl get events --field-selector reason=Preempted - [ ] Confirmez qu'aucun pod critique n'a été évincé involontairement :
kubectl get pods --all-namespaces | grep -v Running - [ ] En cas de problème, revenez en arrière : supprimez la nouvelle classe de priorité et réappliquez la sauvegarde si nécessaire. Note : la suppression d'une classe de priorité n'affecte pas les pods existants qui ont déjà la priorité assignée, mais les nouveaux pods qui y font référence échoueront.
Responsable : Priya Shah, responsable de l'ingénierie de plateforme Fréquence de révision : trimestrielle ou après toute mise à niveau du cluster.
Conclusion
La classe de priorité Kubernetes est un outil puissant pour garantir que les charges de travail critiques obtiennent des ressources en cas de contention. Cependant, une mauvaise configuration peut provoquer une interruption de service. En suivant une approche structurée – inventaire de l'environnement, application sécurisée des configurations, vérification du comportement et préparation aux défaillances – vous pouvez exploiter efficacement les priorités. Commencez par des tests à faible risque, surveillez les événements d'ordonnancement et documentez les procédures de récupération. Un flux de travail opérationnel fiable rend les défaillances visibles, protège les valeurs sensibles, limite les changements et définit la vérification de la récupération avant qu'un incident ne survienne.
Comme prochaine étape, examinez les classes de priorité existantes de votre cluster, identifiez les pods qui n'ont pas de priorités explicites et planifiez un schéma de priorités aligné sur la criticité de votre entreprise. Implémentez-le progressivement avec des tests et une surveillance approfondis.