Sans priorité explicite, un pod critique de paiement et un job de nettoyage batch ont exactement le même poids aux yeux du scheduler : sur un nœud saturé, le premier arrivé prend la place, peu importe son importance réelle pour le métier. PriorityClass corrige ce vide en donnant au scheduler un critère explicite pour trancher.

Une priorité numérique, comparée globalement

Une PriorityClass associe un nom à une valeur numérique ; plus le nombre est élevé, plus la priorité est haute.

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: critical-payment
value: 1000000
globalDefault: false
description: "Réservé aux services de paiement, jamais préemptés en premier."

Cette valeur se compare globalement entre tous les pods du cluster, pas seulement entre pods d’une même équipe ou d’un même namespace : sans discipline collective sur qui a le droit de créer des PriorityClass élevées, une équipe peut accidentellement (ou délibérément) s’octroyer une priorité qui écrase tout le reste. kubectl get priorityclass liste ce qui existe déjà avant d’en créer une nouvelle sans réfléchir au chevauchement.

Ce que la priorité change à l’ordre de scheduling

Un pod de priorité plus élevée passe devant les pods de priorité plus basse dans la file d’attente du scheduler, sans attendre son tour naturel. Sur un cluster avec de la capacité disponible, cet effet reste invisible : tout le monde se place de toute façon. La priorité ne se manifeste que sous contrainte réelle de capacité.

La préemption : évincer pour faire de la place

Quand aucun nœud n’a de capacité disponible pour un pod en attente, le scheduler peut évincer un ou plusieurs pods de priorité inférieure sur un nœud donné, si cette éviction libère assez de place pour le pod prioritaire. Ce n’est pas un mécanisme silencieux : l’événement apparaît dans la description du pod évincé.

# Le pod évincé montre exactement pourquoi
kubectl describe pod low-priority-batch-job
# Events: Preempted by a higher priority pod

La préemption respecte, dans la mesure du possible, les contraintes déjà posées ailleurs : un PodDisruptionBudget sur les pods candidats à l’éviction est pris en compte, le scheduler cherche à violer le moins de PDB possible avant de choisir ses victimes. Ce n’est pas une garantie absolue de respect des PDB sous forte contention, mais une priorité dans la sélection.

preemptionPolicy: Never, pour une priorité sans droit d’éviction

Toutes les priorités élevées ne doivent pas nécessairement évincer. Un pod peut avoir une priorité haute pour passer devant dans la file d’attente, sans jamais avoir le droit de préempter d’autres pods :

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority-no-preempt
value: 100000
preemptionPolicy: Never

Ce réglage convient à des workloads réellement importants mais tolérants à l’attente (un batch prioritaire qui doit passer avant d’autres batchs, sans jamais interrompre un service en production pour autant).

Le piège du globalDefault mal posé

Une seule PriorityClass peut porter globalDefault: true, appliquée automatiquement à tout pod qui n’en spécifie aucune. Fixer ce défaut trop haut élève silencieusement la priorité de tout ce qui ne s’en soucie pas explicitement, ce qui dilue l’utilité même du mécanisme : si presque tout est prioritaire, plus rien ne l’est vraiment.

À retenir

PriorityClass donne au scheduler un critère explicite pour arbitrer entre pods concurrents sous contrainte de capacité, et la préemption en est la conséquence sous pression réelle, pas un mécanisme qui s’active en permanence. preemptionPolicy: Never sépare passer-devant-dans-la-file de droit-d’évincer, une distinction qui compte pour des priorités hautes mais non destructrices. Réserver les priorités les plus élevées aux workloads réellement critiques, et surveiller le globalDefault, évite qu’un mécanisme de protection ne devienne un bruit de fond que plus personne ne respecte. Poser ces garde-fous de capacité fait partie de ce qui distingue un cluster prêt pour la production d’une simple installation par défaut, dès les premières étapes d’une migration Kubernetes.