## 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 sur true sur une PriorityClass, elle devient la valeur par défaut pour les pods qui ne spécifient pas de priorityClassName . Une seule PriorityClass peut avoir globalDefault: 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).

- kubectl configuré avec les autorisations RBAC appropriées. Vous avez besoin des autorisations create , update , delete sur priorityclasses.scheduling.k8s.io et pods si 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.

<style>
.eno-quiz-widget{margin:2rem 0;padding:1.5rem;border-radius:12px;background:var(--eno-surface-lowest,#f7f7f8);border:1px solid var(--eno-border-soft,#e2e2e6);font-family:var(--eno-font-body,Inter,sans-serif)}
.eno-quiz-widget .eno-quiz-kicker{font-family:var(--eno-font-label,"JetBrains Mono",monospace);font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--eno-text-muted,#5f5f68);margin:0 0 .5rem}
.eno-quiz-widget .eno-quiz-question{font-family:var(--eno-font-heading,"Hanken Grotesk",sans-serif);font-size:1.0625rem;font-weight:600;margin:0 0 1rem;color:var(--eno-text-strong,#1a1a1f)}
.eno-quiz-widget .eno-quiz-options{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.eno-quiz-widget .eno-quiz-option{display:block;width:100%;min-height:44px;text-align:left;padding:.625rem .875rem;border-radius:8px;border:1.5px solid var(--eno-border-soft,#e2e2e6);background:#fff;font-size:.9375rem;cursor:pointer;transition:border-color var(--eno-motion-base,180ms ease-out),background var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-option:hover{border-color:var(--eno-primary,#0059bb)}
.eno-quiz-widget .eno-quiz-option:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-option[aria-pressed="true"]{border-color:var(--eno-primary,#0059bb);background:rgb(0 89 187 / 0.06)}
.eno-quiz-widget .eno-quiz-option[data-correct="true"].eno-quiz-revealed{border-color:var(--eno-success,#17803a);background:rgb(23 128 58 / 0.08)}
.eno-quiz-widget .eno-quiz-option[data-correct="false"].eno-quiz-revealed.eno-quiz-was-selected{border-color:var(--eno-error,#ba1a1a);background:var(--eno-error-soft,#ffdad6)}
.eno-quiz-widget .eno-quiz-option-icon{display:inline-block;width:1.1em;margin-right:.4em;font-weight:700}
.eno-quiz-widget .eno-quiz-submit{margin-top:1rem;min-height:44px;padding:.5rem 1.25rem;border-radius:8px;border:none;background:var(--eno-primary,#0059bb);color:#fff;font-weight:600;font-size:.9375rem;cursor:pointer;transition:opacity var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-submit:disabled{opacity:.5;cursor:not-allowed}
.eno-quiz-widget .eno-quiz-submit:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-explanation{margin-top:1rem;padding:.875rem 1rem;border-radius:8px;font-size:.9375rem;line-height:1.5;display:none}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-visible{display:block}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-correct{background:rgb(23 128 58 / 0.08);color:var(--eno-success,#17803a)}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-incorrect{background:var(--eno-error-soft,#ffdad6);color:var(--eno-error,#ba1a1a)}
@media (prefers-reduced-motion: reduce){.eno-quiz-widget *{transition:none!important}}
</style><div class="eno-quiz-widget" role="group" aria-label="Question rapide">
Question rapide 1 sur 2

Quelles sont les deux PriorityClasses intégrées fournies par Kubernetes ?

- system-cluster-critical et system-node-critical
- haute priorité et basse priorité
- priorité par défaut et haute priorité
- critique et normal

<button type="button" class="eno-quiz-submit" disabled>Valider</button>
<div class="eno-quiz-explanation">Kubernetes fournit deux PriorityClasses intégrées : system-cluster-critical pour les composants système critiques pour le cluster, et system-node-critical pour les composants système critiques pour les nœuds individuels.</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.eno-quiz-widget:not([data-eno-quiz-bound])').forEach(function (widget) {
    widget.setAttribute('data-eno-quiz-bound', '1');
    var options = Array.prototype.slice.call(widget.querySelectorAll('.eno-quiz-option'));
    var submitBtn = widget.querySelector('.eno-quiz-submit');
    var explanation = widget.querySelector('.eno-quiz-explanation');
    var selected = null;
    options.forEach(function (opt) {
      opt.addEventListener('click', function () {
        if (widget.hasAttribute('data-eno-quiz-answered')) return;
        options.forEach(function (o) { o.setAttribute('aria-pressed', 'false'); });
        opt.setAttribute('aria-pressed', 'true');
        selected = opt;
        submitBtn.disabled = false;
      });
    });
    submitBtn.addEventListener('click', function () {
      if (!selected || widget.hasAttribute('data-eno-quiz-answered')) return;
      widget.setAttribute('data-eno-quiz-answered', '1');
      submitBtn.disabled = true;
      var correct = selected.getAttribute('data-correct') === 'true';
      options.forEach(function (o) {
        o.classList.add('eno-quiz-revealed');
        if (o === selected) o.classList.add('eno-quiz-was-selected');
        var icon = o.querySelector('.eno-quiz-option-icon');
        if (o.getAttribute('data-correct') === 'true') icon.textContent = '\u2713';
        else if (o === selected) icon.textContent = '\u2717';
      });
      explanation.classList.add('eno-quiz-visible', correct ? 'eno-quiz-correct' : 'eno-quiz-incorrect');
    });
  });
});
</script>

## 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 :

<div class="my-stack-md overflow-x-auto">
<table class="min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Nom de la PriorityClass</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Valeur</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Utilisation prévue</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">system-cluster-critical</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">2000000000 (intégrée, non définie par l&#39;utilisateur)</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Pods système Kubernetes</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">high-priority</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">1000</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Microservices critiques en production</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">medium-priority</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">100</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Charges de travail normales</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">low-priority</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">10</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Tâches par lots, pods de développement</td></tr></tbody>
</table>
</div>
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 :

<div class="my-stack-md overflow-x-auto">
<table class="min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Symptôme</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Cause probable</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Commande de diagnostic</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Pod bloqué en <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">Pending</code> avec l&#39;événement &quot;no PriorityClass with name X found&quot;</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">PriorityClass supprimée ou renommée</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl describe pod &lt;pod-name&gt;</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Pod préempté de manière inattendue</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Un pod à haute priorité a été planifié, le pod à faible priorité avait une priorité inférieure</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl get events --sort-by=&#39;.lastTimestamp&#39;</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Le pod à haute priorité ne peut pas préempter</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">preemptionPolicy: Never</code> sur sa PriorityClass</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl get priorityclass &lt;name&gt; -o yaml</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Le pod obtient la priorité par défaut 0</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Aucun <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">globalDefault</code> défini, le pod n&#39;a pas de <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">priorityClassName</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl get pod &lt;pod-name&gt; -o yaml | grep priorityClassName</code></td></tr></tbody>
</table>
</div>
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 --previous pour vérifier les boucles de crash non liées à la priorité.

- kubectl rollout status deployment/ 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.

<style>
.eno-quiz-widget{margin:2rem 0;padding:1.5rem;border-radius:12px;background:var(--eno-surface-lowest,#f7f7f8);border:1px solid var(--eno-border-soft,#e2e2e6);font-family:var(--eno-font-body,Inter,sans-serif)}
.eno-quiz-widget .eno-quiz-kicker{font-family:var(--eno-font-label,"JetBrains Mono",monospace);font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--eno-text-muted,#5f5f68);margin:0 0 .5rem}
.eno-quiz-widget .eno-quiz-question{font-family:var(--eno-font-heading,"Hanken Grotesk",sans-serif);font-size:1.0625rem;font-weight:600;margin:0 0 1rem;color:var(--eno-text-strong,#1a1a1f)}
.eno-quiz-widget .eno-quiz-options{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.eno-quiz-widget .eno-quiz-option{display:block;width:100%;min-height:44px;text-align:left;padding:.625rem .875rem;border-radius:8px;border:1.5px solid var(--eno-border-soft,#e2e2e6);background:#fff;font-size:.9375rem;cursor:pointer;transition:border-color var(--eno-motion-base,180ms ease-out),background var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-option:hover{border-color:var(--eno-primary,#0059bb)}
.eno-quiz-widget .eno-quiz-option:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-option[aria-pressed="true"]{border-color:var(--eno-primary,#0059bb);background:rgb(0 89 187 / 0.06)}
.eno-quiz-widget .eno-quiz-option[data-correct="true"].eno-quiz-revealed{border-color:var(--eno-success,#17803a);background:rgb(23 128 58 / 0.08)}
.eno-quiz-widget .eno-quiz-option[data-correct="false"].eno-quiz-revealed.eno-quiz-was-selected{border-color:var(--eno-error,#ba1a1a);background:var(--eno-error-soft,#ffdad6)}
.eno-quiz-widget .eno-quiz-option-icon{display:inline-block;width:1.1em;margin-right:.4em;font-weight:700}
.eno-quiz-widget .eno-quiz-submit{margin-top:1rem;min-height:44px;padding:.5rem 1.25rem;border-radius:8px;border:none;background:var(--eno-primary,#0059bb);color:#fff;font-weight:600;font-size:.9375rem;cursor:pointer;transition:opacity var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-submit:disabled{opacity:.5;cursor:not-allowed}
.eno-quiz-widget .eno-quiz-submit:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-explanation{margin-top:1rem;padding:.875rem 1rem;border-radius:8px;font-size:.9375rem;line-height:1.5;display:none}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-visible{display:block}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-correct{background:rgb(23 128 58 / 0.08);color:var(--eno-success,#17803a)}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-incorrect{background:var(--eno-error-soft,#ffdad6);color:var(--eno-error,#ba1a1a)}
@media (prefers-reduced-motion: reduce){.eno-quiz-widget *{transition:none!important}}
</style><div class="eno-quiz-widget" role="group" aria-label="Question rapide">
Question rapide 2 sur 2

Quelle commande crée une PriorityClass nommée 'high-priority' qui ne peut pas préempter les pods de priorité inférieure ?

- kubectl create priorityclass high-priority --value=1000 --description="high priority" --preemption-policy="Never"
- kubectl create priorityclass high-priority --value=1000 --description="high priority" --preemption-policy="PreemptLowerPriority"
- kubectl create priorityclass high-priority --value=1000 --global-default=true --description="high priority"
- kubectl create priorityclass high-priority --value=1000 --description="high priority"

<button type="button" class="eno-quiz-submit" disabled>Valider</button>
<div class="eno-quiz-explanation">L&#39;exemple montre que pour créer une classe de haute priorité qui ne peut pas préempter les pods de priorité inférieure, vous devez inclure le drapeau --preemption-policy=&quot;Never&quot;.</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.eno-quiz-widget:not([data-eno-quiz-bound])').forEach(function (widget) {
    widget.setAttribute('data-eno-quiz-bound', '1');
    var options = Array.prototype.slice.call(widget.querySelectorAll('.eno-quiz-option'));
    var submitBtn = widget.querySelector('.eno-quiz-submit');
    var explanation = widget.querySelector('.eno-quiz-explanation');
    var selected = null;
    options.forEach(function (opt) {
      opt.addEventListener('click', function () {
        if (widget.hasAttribute('data-eno-quiz-answered')) return;
        options.forEach(function (o) { o.setAttribute('aria-pressed', 'false'); });
        opt.setAttribute('aria-pressed', 'true');
        selected = opt;
        submitBtn.disabled = false;
      });
    });
    submitBtn.addEventListener('click', function () {
      if (!selected || widget.hasAttribute('data-eno-quiz-answered')) return;
      widget.setAttribute('data-eno-quiz-answered', '1');
      submitBtn.disabled = true;
      var correct = selected.getAttribute('data-correct') === 'true';
      options.forEach(function (o) {
        o.classList.add('eno-quiz-revealed');
        if (o === selected) o.classList.add('eno-quiz-was-selected');
        var icon = o.querySelector('.eno-quiz-option-icon');
        if (o.getAttribute('data-correct') === 'true') icon.textContent = '\u2713';
        else if (o === selected) icon.textContent = '\u2717';
      });
      explanation.classList.add('eno-quiz-visible', correct ? 'eno-quiz-correct' : 'eno-quiz-incorrect');
    });
  });
});
</script>

## 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 apply avec --dry-run=server pour 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=server d'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 yaml et vérifiez value , 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 priorityclass pour réviser.

- Aucun globalDefault dé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.