E-NO
Kubernetes 8 min de lecture

Priorité et préemption des pods Kubernetes : erreurs courantes et solutions avec exemples pratiques

calendar_today Publié : 2026-08-30
update Dernière mise à jour : 2026-08-30
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Priorité et préemption des pods Kubernetes : erreurs courantes et solutions avec exemples pratiques ».

Introduction

La priorité et la préemption des pods sont des fonctionnalités critiques de planification de Kubernetes qui vous aident à exécuter des charges de travail critiques lorsque les ressources du cluster sont rares. Mais des erreurs de configuration peuvent silencieusement casser la planification, évincer les mauvais pods ou laisser des pods de haute priorité bloqués en état Pending. Ce guide passe en revue les erreurs courantes, les correctifs pratiques et les étapes de vérification avec des commandes et des exemples concrets. Il est destiné aux développeurs, aux ingénieurs DevOps et aux équipes plateforme qui exploitent des clusters Kubernetes en production.

Nous mettons l'accent sur la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets dans les exemples, vérifier le résultat et documenter les chemins de récupération. Chaque correctif inclut la sortie ou le signal attendu pour que vous sachiez s'il a fonctionné.

Inventaire de la version et de l'environnement

Avant de changer quoi que ce soit, confirmez la version de votre cluster, la configuration du planificateur et les définitions de ressources pertinentes. Le comportement de la priorité et de la préemption a évolué au fil des versions de Kubernetes ; par exemple, les PriorityClasses non préemptives sont devenues stables en 1.24. Vérifiez toujours ce que votre cluster prend en charge.

Vérifier la version du cluster :

kubectl version --short

La sortie attendue montre les versions client et serveur, par exemple Server Version: v1.27.3.

Vérifier si l'API PriorityClass est disponible :

kubectl api-versions | grep scheduling.k8s.io

La sortie attendue inclut scheduling.k8s.io/v1.

Lister les PriorityClasses existantes :

kubectl get priorityclass

La sortie attendue inclut les noms, les valeurs et les indicateurs globalDefault. Si cette commande échoue ou ne renvoie rien, aucune PriorityClass n'existe encore.

Vérifier la configuration du planificateur : Si vous utilisez un planificateur personnalisé ou avez modifié les paramètres de kube-scheduler, vérifiez que la préemption n'est pas désactivée. Dans la politique du planificateur ou la KubeSchedulerConfiguration, assurez-vous que disablePreemption: false (la valeur par défaut). Pour les clusters utilisant le planificateur par défaut, c'est rarement un problème, mais des configurations personnalisées peuvent le définir à true.

Prérequis :

  • Accès administrateur du cluster pour créer des PriorityClasses et modifier des charges de travail.
  • kubectl configuré avec le contexte approprié.
  • Compréhension de vos demandes de ressources et de la capacité des nœuds.

Observation en lecture seule avant les modifications :

kubectl get pods -o wide --all-namespaces | grep -i pending

Cela montre les pods actuellement bloqués en état Pending, un premier symptôme courant.

kubectl describe pod <pod-name> -n <namespace>

Recherchez des événements comme 0/3 nodes are available: 3 Insufficient cpu. preemption: 0/3 nodes are available: 3 No preemption victims found for incoming pod. Cela vous indique si la préemption est même tentée.

Exemple d'inventaire de l'environnement :

  • Version Kubernetes : v1.26.5
  • Planificateur : kube-scheduler par défaut
  • PriorityClasses définies : high-priority (valeur 1000), default (valeur 0), low-priority (valeur -10)
  • Capacité des nœuds : 3 nœuds worker, chacun 4 vCPU / 8 Go de RAM
  • Charges de travail : web (low-priority), api (high-priority), batch (medium-priority)

Gardez les tests locaux petits avant de déployer des changements à l'échelle du cluster. Appliquez un manifeste à la fois et inspectez les résultats.

Question rapide 1 sur 2

Que se passe-t-il si un Pod de priorité plus élevée a besoin de ressources DRA actuellement utilisées par un Pod de priorité plus basse ?

Le planificateur Kubernetes ne prend pas en charge la préemption pour les ressources DRA, de sorte qu'un Pod de priorité plus élevée ayant besoin de ressources DRA ne peut pas préempter un Pod existant qui les utilise ; il reste en attente jusqu'à ce que le périphérique soit disponible.

Chemin de configuration sûr

Pour utiliser correctement la priorité des pods, vous devez définir des PriorityClasses et les référencer dans les spécifications des pods. Les erreurs courantes incluent l'absence de globalDefault, un mauvais preemptionPolicy et des valeurs de priorité qui ne correspondent pas au comportement prévu.

Étape 1 : Créer une PriorityClass

Exemple de PriorityClass pour les charges de travail critiques :

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000
globalDefault: false
preemptionPolicy: PreemptLowerPriority
description: "Pour les pods API critiques qui doivent être planifiés même sous pression de ressources."

Appliquez-la :

kubectl apply -f high-priority-class.yaml

Sortie attendue : priorityclass.scheduling.k8s.io/high-priority created.

Vérifiez :

kubectl get priorityclass high-priority -o yaml

Vérifiez que value et preemptionPolicy sont corrects.

Erreur courante : Définir preemptionPolicy: Never alors que vous avez réellement besoin de préemption. Si un pod de haute priorité a preemptionPolicy: Never, il n'évincera pas les pods de priorité inférieure et peut rester en Pending. Utilisez Never uniquement pour les pods qui ne doivent jamais provoquer d'éviction, comme les add-ons de cluster qui peuvent attendre.

Étape 2 : Référencer la PriorityClass dans un Pod ou un Deployment

Exemple de spécification de pod :

apiVersion: v1
kind: Pod
metadata:
  name: api-pod
spec:
  priorityClassName: high-priority
  containers:
  - name: api
    image: nginx
    resources:
      requests:
        cpu: "2"
        memory: "1Gi"

Appliquez et vérifiez :

kubectl apply -f api-pod.yaml
kubectl get pod api-pod -o yaml | grep priorityClassName

La sortie attendue inclut priorityClassName: high-priority.

Erreur courante : Mal orthographier le priorityClassName ou référencer une PriorityClass inexistante. Le pod sera rejeté avec une erreur comme PriorityClass "high-priorty" not found. Vérifiez toujours que le nom correspond exactement.

Étape 3 : Définir une valeur par défaut globale (facultatif)

Si vous voulez que tous les pods sans priorityClassName reçoivent une priorité par défaut, créez une PriorityClass avec globalDefault: true. Une seule peut être la valeur par défaut globale par cluster. Exemple :

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: default-priority
value: 0
globalDefault: true
preemptionPolicy: PreemptLowerPriority

Appliquez et vérifiez :

kubectl apply -f default-priority.yaml
kubectl get priorityclass

La sortie doit montrer default-priority avec GLOBAL DEFAULT à true.

Erreur courante : Avoir plusieurs PriorityClasses avec globalDefault: true. Le serveur API rejette la seconde avec une erreur. Une seule peut être la valeur par défaut globale.

Vérification de la configuration sûre

Après l'application, testez la planification dans un namespace contrôlé. Créez un pod de basse priorité qui consomme des ressources, puis un pod de haute priorité qui devrait le préempter.

Exemple de pod de basse priorité (utilise toute la capacité du nœud) :

apiVersion: v1
kind: Pod
metadata:
  name: low-priority-pod
  namespace: test-preemption
spec:
  priorityClassName: low-priority
  containers:
  - name: stress
    image: polinux/stress
    resources:
      requests:
        cpu: "2"
        memory: "1Gi"

Créez le namespace et le pod :

kubectl create namespace test-preemption
kubectl apply -f low-priority-pod.yaml

Attendez qu'il soit en état Running.

Maintenant, créez un pod de haute priorité qui demande plus que disponible :

apiVersion: v1
kind: Pod
metadata:
  name: high-priority-pod
  namespace: test-preemption
spec:
  priorityClassName: high-priority
  containers:
  - name: api
    image: nginx
    resources:
      requests:
        cpu: "1"
        memory: "512Mi"

Appliquez :

kubectl apply -f high-priority-pod.yaml

Vérifiez le statut :

kubectl get pods -n test-preemption

Attendu : high-priority-pod devient Running, et low-priority-pod est en Terminating ou Evicted. Sinon, inspectez les événements avec kubectl describe pod high-priority-pod -n test-preemption.

Vérification et diagnostics

Lorsque les pods ne sont pas planifiés comme prévu, rassemblez systématiquement des diagnostics.

1. Vérifier le statut du pod et les événements

kubectl get pods -n <namespace> -o wide
kubectl describe pod <pod-name> -n <namespace>

Recherchez des événements mentionnant la préemption, la priorité ou des ressources insuffisantes.

Exemple d'événement problématique :

0/3 nodes are available: 3 Insufficient cpu. preemption: 0/3 nodes are available: 3 No preemption victims found for incoming pod.

Cela signifie que le planificateur n'a pas trouvé de pods de priorité inférieure à évincer pour faire de la place. Les causes incluent :

  • Aucun pod de priorité inférieure n'existe sur les nœuds.
  • Les pods de priorité inférieure ont preemptionPolicy: Never (ils ne peuvent donc pas être préemptés) ou sont dans un PodDisruptionBudget qui empêche l'éviction.
  • Le pod de haute priorité lui-même a preemptionPolicy: Never.
  • Les nœuds ont des taints ou d'autres contraintes empêchant la planification même après préemption.

2. Vérifier les valeurs et politiques des PriorityClasses

kubectl get priorityclass <name> -o yaml

Vérifiez value, preemptionPolicy et globalDefault.

Erreur courante : Valeurs de priorité mal définies. Une valeur numérique plus élevée signifie une priorité plus élevée. Si votre classe "haute" priorité a la valeur 10 et "basse" a 1000, vous avez inversé les priorités. Utilisez une échelle claire, par exemple 1000 pour critique, 100 pour normal, -10 pour best-effort.

3. Inspecter les journaux du planificateur (si vous y avez accès)

Si vous utilisez kube-scheduler comme pod statique, affichez les journaux :

kubectl logs -n kube-system kube-scheduler-<node-name> | grep -i preempt

Recherchez des lignes comme Attempting to preempt pods for pod ... ou des erreurs sur la recherche de victimes.

Pour les clusters gérés (EKS, GKE, AKS), les journaux du planificateur peuvent être disponibles via la journalisation du fournisseur cloud.

4. Vérifier les PodDisruptionBudgets

Les PodDisruptionBudgets (PDB) peuvent bloquer la préemption si l'éviction violerait le budget.

kubectl get pdb -n <namespace>

Si un pod de priorité inférieure est protégé par un PDB avec minAvailable: 1, le planificateur peut ne pas l'évincer, ce qui laisse le pod de priorité supérieure en Pending.

Exemple : Un déploiement avec une réplique et un PDB minAvailable: 1. Le pod unique ne peut pas être évincé, donc aucune préemption ne se produit.

5. Vérifier les demandes de ressources et l'allocatable du nœud

Parfois, la préemption échoue car le pod entrant demande plus de ressources que tout nœud ne peut fournir même après avoir évincé tous les pods de priorité inférieure.

kubectl describe node <node-name> | grep -A5 "Allocated resources"

Comparez les demandes du pod avec la capacité allocatable du nœud.

Erreur courante : Cela se produit avec des demandes surdimensionnées ; réduisez les demandes de ressources du pod ou ajoutez des nœuds.

Question rapide 2 sur 2

Lequel des éléments suivants n'est PAS un facteur dans le classement d'éviction en cas de pression sur le nœud du kubelet ?

Le kubelet classe les pods pour éviction en fonction de si l'utilisation de la ressource en pénurie dépasse les requêtes, de la priorité du Pod et de la quantité d'utilisation de la ressource par rapport aux requêtes. La classe QoS n'est pas directement répertoriée comme facteur de classement.

Modes de défaillance et récupération

Voici des scénarios de défaillance spécifiques et des actions de récupération étape par étape.

Défaillance 1 : Pod de haute priorité bloqué en Pending avec "No preemption victims found"

Symptôme : L'événement dit No preemption victims found for incoming pod.

Cause : Aucun pod de priorité inférieure sur les nœuds qui satisfont d'autres contraintes de planification, ou les pods de priorité inférieure sont non préemptifs.

Correctif :

  1. Vérifiez les valeurs de priorité : kubectl get priorityclass.
  2. Assurez-vous que les pods de priorité inférieure existent et sont préemptibles (preemptionPolicy par défaut à PreemptLowerPriority).
  3. Si vous devez évincer des pods de même priorité, vous pouvez utiliser une éviction manuelle ou l'autoscaling du cluster.
  4. Considérez si le pod de haute priorité pourrait tolérer un autre nœud (tolérations, nodeSelector).

Vérification : Après ajustement, observez le pod :

kubectl get pod <name> -n <namespace> -w

Il doit passer à Running.

Défaillance 2 : Éviction involontaire de pods critiques

Symptôme : Un pod critique est évincé par un pod de priorité supérieure de manière inattendue.

Cause : Le pod critique avait une priorité basse ou aucune priorité (par défaut 0), et un nouveau pod de priorité supérieure est arrivé.

Correctif :

  1. Examinez les priorityClassNames des pods existants.
  2. Créez ou attribuez une PriorityClass appropriée aux pods critiques (par exemple, valeur 10000) et mettez à jour leurs déploiements.
  3. Envisagez de définir preemptionPolicy: Never pour les pods qui ne doivent jamais préempter les autres, mais notez que cela les empêche aussi d'être préemptés (ils deviennent non préemptifs dans les deux sens).
  4. Utilisez des PodDisruptionBudgets pour protéger les pods critiques contre les interruptions volontaires, mais notez que les PDB n'empêchent pas la préemption dans tous les cas (la préemption n'est pas une interruption volontaire). Pour des garanties plus fortes, utilisez une PriorityClass avec une valeur élevée et assurez-vous qu'aucun pod de priorité supérieure n'est sans nécessité.

Vérification : Vérifiez que le pod critique reste Running lors du prochain événement de mise à l'échelle.

Défaillance 3 : Erreur PriorityClass introuvable

Symptôme : Lors de l'application d'un manifeste de pod, vous obtenez :

Error from server (NotFound): priorityclasses.scheduling.k8s.io "my-priority" not found

Correctif : Créez d'abord la PriorityClass, ou corrigez la référence de nom dans la spécification du pod.

Vérification : kubectl get priorityclass montre la classe attendue.

Défaillance 4 : La préemption ne se produit pas en raison de la préemption désactivée dans le planificateur

Symptôme : Même avec des PriorityClasses correctes, aucune préemption ne se produit ; les pods de haute priorité restent en Pending.

Cause : kube-scheduler peut avoir disablePreemption: true dans sa configuration.

Correctif :

  1. Vérifiez la configuration du planificateur (dans kube-system, configmap ou manifeste de pod statique).
  2. Définissez disablePreemption: false (ou supprimez la ligne).
  3. Redémarrez kube-scheduler.

Vérification : Après redémarrage, observez les journaux du planificateur pour les tentatives de préemption.

Défaillance 5 : La préemption provoque des évictions en cascade

Symptôme : Plusieurs pods sont évincés en réaction en chaîne lorsqu'un seul pod de haute priorité est planifié.

Cause : La préemption peut évincer un pod, mais si les ressources sont encore insuffisantes, elle en évince davantage. Cela peut se produire si le pod de haute priorité demande beaucoup de ressources.

Correctif :

  • Dimensionnez correctement les demandes du pod de haute priorité.
  • Ajoutez plus de nœuds ou utilisez l'autoscaler du cluster.
  • Utilisez les priorités avec soin : n'attribuez une haute priorité qu'aux charges de travail vraiment critiques.
  • Envisagez d'utiliser preemptionPolicy: Never pour les pods de haute priorité qui peuvent attendre.

Vérification : Surveillez le nombre de pods et les événements d'éviction avec kubectl get events --sort-by=.lastTimestamp.

Liste de contrôle des opérations

Utilisez cette liste de contrôle pour résoudre systématiquement les problèmes de priorité et de préemption des pods.

ÉtapeActionCommande / ExempleRésultat attendu
1Vérifier la version du cluster et l'APIkubectl version --short et kubectl api-versions | grep scheduling.k8s.ioVersion serveur >=1.14 et API scheduling présente
2Lister les PriorityClasseskubectl get priorityclassToutes les classes attendues avec des valeurs correctes
3Vérifier les pods en attentekubectl get pods --all-namespaces | grep PendingIdentifier les pods nécessitant une attention
4Décrire un pod en attentekubectl describe pod <name> -n <ns>Rechercher des événements liés à la préemption
5Inspecter le YAML de la PriorityClasskubectl get priorityclass <name> -o yamlVérifier value, preemptionPolicy, globalDefault
6Vérifier les PodDisruptionBudgetskubectl get pdb -n <ns>Identifier les PDB qui peuvent bloquer l'éviction
7Vérifier la config du planificateur (si personnalisé)kubectl -n kube-system get configmap kube-scheduler -o yaml ou inspecter le manifeste du pod statiqueAssurer disablePreemption: false
8Examiner les ressources du nœudkubectl describe node <node>Comparer allocatable vs demandé
9Tester la préemption dans un namespace isoléCréer des pods basse et haute priorité comme montréLe pod haute priorité s'exécute, le pod basse priorité est évincé
10Documenter les étapes de récupérationEnregistrer ce qui a été changé et comment revenir en arrièreRunbook mis à jour

Remplacez <name>, <ns>, <node> par vos noms de ressources réels. Cette liste de contrôle vous aide à couvrir les points de défaillance courants sans manquer de diagnostics critiques.

Conclusion

La priorité et la préemption des pods sont puissantes mais doivent être configurées avec soin. Des erreurs courantes comme des valeurs de priorité inversées, des PriorityClasses manquantes, des politiques de préemption mal configurées et des demandes de ressources supérieures à la capacité du nœud peuvent provoquer des échecs de planification ou des évictions inattendues. En observant systématiquement l'état du cluster, en appliquant des changements minimaux et en vérifiant avec des commandes concrètes, vous pouvez résoudre la plupart des problèmes sans conjectures.

Prochaines étapes : commencez par une vérification à faible risque dans un namespace de test, enregistrez l'état actuel, appliquez une PriorityClass et simulez un scénario de préemption comme décrit. Surveillez les résultats et ajustez. Rappelez-vous que la préemption est un dernier recours ; pour les charges de travail critiques, dimensionnez correctement les demandes de ressources, utilisez l'autoscaling du cluster et définissez des priorités appropriées pour minimiser les perturbations.

Un flux de travail opérationnel fiable rend les défaillances visibles, protège les valeurs sensibles, limite les modifications aux ressources prévues et définit la vérification de la récupération avant qu'un incident ne force une décision.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO