Introduction
Les Priority Classes Kubernetes contrôlent quels pods sont ordonnancés en premier lorsque votre cluster est à court de ressources. Les équipes qui gèrent les priority classes manuellement se heurtent toujours au même obstacle : une seule valeur mal saisie dans kubectl apply peut affamer des services critiques ou laisser des charges de travail à faible priorité bloquer le trafic de production. La solution n'est pas d'éviter les priority classes, mais de traiter chaque modification comme un déploiement en production : versionnée, observable, réversible et automatisée via CI/CD.
Cet article présente une mise en œuvre pratique de l'automatisation CI/CD des Priority Classes Kubernetes. Il couvre l'inventaire de l'environnement, un chemin de configuration sécurisé, la vérification, les modes de défaillance et une liste de contrôle opérationnelle finale. Chaque section comprend des commandes concrètes, des extraits de configuration, les sorties attendues et les décisions de récupération. Le public visé est constitué de développeurs, de consultants DevOps et d'équipes techniques de startups qui utilisent déjà Kubernetes mais veulent un contrôle plus strict de l'ordonnancement des pods sans éditer manuellement l'état du cluster.
La philosophie opérationnelle est simple : observez avant de changer, limitez le rayon d'impact, utilisez des espaces réservés au lieu de secrets, vérifiez chaque étape et documentez la récupération si l'état attendu n'est pas atteint.
Inventaire de la version et de l'environnement
Avant d'automatiser quoi que ce soit, établissez l'état exact de votre cluster et des outils qui toucheront aux Priority Classes. Cela évite l'échec classique de CI/CD où un pipeline fonctionne sur un poste de développeur mais casse en staging parce que la version de Kubernetes ou les règles RBAC diffèrent.
Identifiez la version du cluster et la disponibilité de l'API
Les Priority Classes font partie du groupe d'API scheduling.k8s.io. La ressource est stable depuis Kubernetes 1.14, mais les versions antérieures nécessitent apiVersion: scheduling.k8s.io/v1beta1. Vérifiez la version du serveur et confirmez que l'API est servie :
kubectl version --short
# Sortie attendue (exemple) :
# Client Version: v1.28.3
# Server Version: v1.28.5
kubectl api-versions | grep scheduling.k8s.io
# Sortie attendue :
scheduling.k8s.io/v1
Si vous voyez scheduling.k8s.io/v1beta1, votre cluster est antérieur à 1.14 et vous devez ajuster le manifeste en conséquence. Si le groupe d'API est entièrement absent, les Priority Classes ne sont pas activées dans votre distribution ; ne procédez pas à l'automatisation tant qu'un administrateur n'a pas activé la fonctionnalité.
Vérifiez les Priority Classes existantes et leur impact
Listez toutes les priority classes et leurs valeurs. La valeur est un entier ; plus le nombre est élevé, plus la priorité est haute. Kubernetes réserve les valeurs supérieures à 1 000 000 000 pour les composants critiques du système.
kubectl get priorityclass
# Sortie attendue (exemple) :
NAME VALUE GLOBAL-DEFAULT AGE
system-cluster-critical 2000000000 false 365d
system-node-critical 2000001000 false 365d
high-priority 1000 false 30d
medium-priority 100 false 30d
low-priority -10 false 30d
Notez la colonne GLOBAL-DEFAULT. Une seule priority class peut être la valeur par défaut globale ; un réglage incorrect peut amener tous les pods à hériter d'une priorité inattendue. Enregistrez les valeurs par défaut actuelles et quelles charges de travail utilisent quelle classe :
kubectl get pods --all-namespaces -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,PRIORITY:.spec.priorityClassName' | head -20
# Sortie attendue (exemple) :
NAMESPACE NAME PRIORITY
kube-system coredns-558bd4d5db-8n2xk system-cluster-critical
kube-system etcd-minikube system-node-critical
payments payments-api-6d9f7c8b5f-4x2qz high-priority
logging fluentd-ds-7h9k2 medium-priority
Faites attention aux pods avec une colonne PRIORITY vide. Ils utilisent la priority class par défaut globale, ce qui peut ne pas être ce que vous attendez.
Vérifiez les autorisations RBAC pour le compte de service CI/CD
Votre pipeline aura besoin de l'autorisation de lire, créer, mettre à jour et supprimer les priority classes. Créez un compte de service et un rôle dédiés, au lieu d'utiliser un jeton cluster-admin. Cela limite les dégâts si les identifiants CI/CD fuient.
Exemple de manifeste priority-class-rbac.yaml :
apiVersion: v1
kind: ServiceAccount
metadata:
name: priority-class-deployer
namespace: ci-cd
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: priority-class-editor
rules:
- apiGroups: ["scheduling.k8s.io"]
resources: ["priorityclasses"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: priority-class-deployer-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: priority-class-editor
subjects:
- kind: ServiceAccount
name: priority-class-deployer
namespace: ci-cd
Appliquez-le et vérifiez que le compte de service peut lister les priority classes :
kubectl apply -f priority-class-rbac.yaml
# Sortie attendue :
serviceaccount/priority-class-deployer created
clusterrole.rbac.authorization.k8s.io/priority-class-editor created
clusterrolebinding.rbac.authorization.k8s.io/priority-class-deployer-binding created
kubectl auth can-i list priorityclasses --as=system:serviceaccount:ci-cd:priority-class-deployer
# Sortie attendue :
yes
Si vous voyez no, inspectez le role binding et l'orthographe du groupe d'API.
Capturez l'état avant changement pour le retour arrière
Avant tout changement automatisé, videz les priority classes actuelles dans un fichier pour pouvoir revenir exactement en arrière si nécessaire :
kubectl get priorityclass -o yaml > priorityclasses-backup-$(date +%Y%m%d-%H%M%S).yaml
Stockez cette sauvegarde dans un référentiel d'artefacts sécurisé ou comme artefact de pipeline, pas seulement dans le journal de build.
Chemin de configuration sécurisé
Le cœur de l'automatisation est de passer d'un kubectl apply manuel à un pipeline revu et testé. Le chemin sûr échelonne les changements : d'abord vers un espace de noms ou un cluster de test, puis vers la production avec une approche canari ou blue-green.
Définissez les manifestes de Priority Class dans Git
Stockez vos définitions de priority class dans un référentiel versionné, avec un fichier par classe et une convention de nommage qui correspond à vos environnements. Par exemple :
priority-classes/
base/
high-priority.yaml
medium-priority.yaml
low-priority.yaml
overlays/
dev/
kustomization.yaml
staging/
kustomization.yaml
prod/
kustomization.yaml
Utilisez Kustomize pour gérer les valeurs spécifiques à l'environnement (par exemple, des valeurs plus basses en dev, plus hautes en prod).
Exemple de base/high-priority.yaml :
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000
globalDefault: false
description: "Utilisé pour le traitement des paiements et les API orientées utilisateur"
preemptionPolicy: PreemptLowerPriority
Remarque : preemptionPolicy est défini explicitement sur PreemptLowerPriority ; c'est la valeur par défaut mais la rendre visible évite les surprises.
Utilisez d'abord un essai à vide (dry-run)
N'appliquez jamais directement. Exécutez toujours kubectl apply --dry-run=client ou --dry-run=server pour valider la syntaxe et les règles d'admission côté serveur :
kubectl apply -f base/high-priority.yaml --dry-run=client
# Sortie attendue :
priorityclass.scheduling.k8s.io/high-priority created (dry run)
Pour une vérification plus approfondie, utilisez --dry-run=server :
kubectl apply -f base/high-priority.yaml --dry-run=server
# Sortie attendue :
priorityclass.scheduling.k8s.io/high-priority created (server dry run)
Si le serveur rejette le changement en raison de règles de validation ou de webhooks d'admission, vous verrez une erreur ici au lieu de casser la production.
Étape de pipeline : appliquer avec diff et revue
Un pipeline CI/CD minimal (par exemple, GitHub Actions, GitLab CI ou Jenkins) pour les mises à jour de priority class devrait inclure les étapes suivantes :
- Lint (analyse statique) : Utilisez
kubeconformoukubectl apply --dry-run=clientdans le pipeline. - Diff : Comparez l'état actuel du cluster avec l'état souhaité en utilisant
kubectl diff:
kubectl diff -f base/high-priority.yaml
# Sortie attendue (si des changements existent) :
# - value: 1000
# + value: 2000
- Approbation : Exigez une étape d'approbation manuelle ou une revue de PR avant d'appliquer en production.
- Appliquer : Exécutez
kubectl apply -f base/high-priority.yaml. - Vérifier : Vérifiez que la priority class est mise à jour et qu'aucun pod non prévu n'a changé de priorité.
Exemple d'extrait de job GitHub Actions (en utilisant azure/k8s-actions ou simplement kubectl) :
name: Apply Priority Class
on:
push:
branches: [ main ]
paths: [ 'priority-classes/base/**' ]
jobs:
apply:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Set up kubectl
uses: azure/setup-kubectl@v4
with:
version: 'v1.28.0'
- name: Run dry-run
run: kubectl apply -f priority-classes/base/high-priority.yaml --dry-run=client
- name: Apply
run: kubectl apply -f priority-classes/base/high-priority.yaml
- name: Verify
run: |
kubectl get priorityclass high-priority -o jsonpath='{.value}'
echo "Valeur attendue : 1000"
IMPORTANT : Le pipeline doit utiliser le jeton du compte de service dédié et non un kubeconfig personnel. Respectez le principe du moindre privilège.
Déploiement progressif avec isolation par espace de noms
Si votre tolérance au risque est faible, introduisez la nouvelle priority class dans un espace de noms de staging d'abord, exécutez une charge de travail canari et observez son comportement d'ordonnancement avant de la rendre utilisable à l'échelle du cluster.
- Créez la priority class dans le cluster (mais ne l'attribuez pas encore à un pod de production).
- Dans un espace de noms canari, déployez une charge de travail de test avec
priorityClassName: high-priority. - Vérifiez que le pod obtient la priorité attendue et est ordonnancé correctement, même sous pression de ressources (simulez la pression en créant de nombreux pods à faible priorité).
- Après validation, commencez à déployer la priority class vers les charges de travail de production par petits lots.
Utilisez des tags Git pour les points de retour arrière
Chaque fusion vers la branche principale devrait produire une version taguée des manifestes. Ce tag devient votre carte de retour arrière :
git tag -a priority-class-v1.2.0 -m "high-priority augmentée de 1000 à 2000"
git push origin priority-class-v1.2.0
Si quelque chose tourne mal, vous pouvez faire git checkout priority-class-v1.1.0 et appliquer ces manifestes pour revenir en arrière.
Vérification et diagnostic
L'automatisation n'est bonne que si sa vérification l'est. Après avoir appliqué les changements, vous devez confirmer que l'effet prévu s'est produit et qu'aucun effet secondaire non prévu n'est apparu.
Vérifications immédiates après application
Exécutez ces commandes immédiatement après que le pipeline a appliqué le changement :
- Vérifiez l'objet PriorityClass :
kubectl get priorityclass high-priority -o yaml
# Extrait de sortie attendu :
# value: 2000
# globalDefault: false
# preemptionPolicy: PreemptLowerPriority
- Vérifiez quels pods utilisent la classe :
kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,PRIORITY:.spec.priorityClassName' | grep high-priority
# Sortie attendue (exemple) :
payments payments-api-6d9f7c8b5f-4x2qz high-priority
- Vérifiez les événements d'ordonnancement pour tout pod affecté par le changement :
kubectl describe pod payments-api-6d9f7c8b5f-4x2qz -n payments | grep -A 10 Events
# Cherchez les événements 'Scheduled', 'FailedScheduling' ou 'Preempted'.
Détection de préemption non intentionnelle
Lorsque vous augmentez la valeur d'une priority class, les pods avec cette classe peuvent préempter les pods de priorité inférieure. Cela peut être souhaitable (par exemple, services critiques) ou désastreux (par exemple, un job batch évincé en plein milieu d'une exécution). Après application, vérifiez les événements de préemption à l'échelle du cluster :
kubectl get events --all-namespaces --field-selector reason=Preempted -o wide
# Si cela renvoie des événements, examinez quels pods ont été évincés.
Si la préemption a causé des problèmes, baissez la valeur ou ajustez le mélange de charges de travail.
Vérification continue : métriques et alertes
Mettez en place des alertes basées sur des métriques qui reflètent la santé des priority classes :
- Pods non ordonnançables avec haute priorité : Si un pod avec
high-priorityne peut pas être ordonnancé pendant plus de 2 minutes, alertez. - Taux de mutation des priority classes : Alertez si une priority class est modifiée plus d'une fois par heure (peut indiquer une mauvaise configuration ou des boucles de pipeline).
- Journaux d'audit d'API : Surveillez les tentatives non autorisées de modification des priority classes.
Exemple de règle d'alerte Prometheus :
groups:
- name: priority-class
rules:
- alert: HighPriorityPodUnschedulable
expr: kube_pod_status_unschedulable{priority_class="high-priority"} > 0
for: 2m
labels:
severity: critical
annotations:
summary: "Le pod à haute priorité {{ $labels.pod }} n'est pas ordonnançable"
Si vous utilisez les journaux d'audit Kubernetes, filtrez pour la ressource priorityclasses et alertez sur toute create ou update en dehors du compte de service du pipeline CI/CD.
Guide de diagnostic pour les problèmes courants
| Symptôme | Cause probable | Commande de diagnostic | Correction |
|---|---|---|---|
kubectl apply échoue avec forbidden | RBAC manquant | kubectl auth can-i update priorityclass/<name> --as=system:serviceaccount:ci-cd:priority-class-deployer | Mettez à jour le ClusterRole si nécessaire |
| Le pod obtient une priorité différente de celle attendue | La valeur par défaut globale remplace la classe | kubectl get priorityclass -o jsonpath='{.items[?(@.globalDefault==true)].metadata.name}' | Définissez globalDefault: false sur la valeur par défaut non souhaitée, ou assignez explicitement priorityClassName au pod |
| Pod évincé pendant le déploiement | Préemption déclenchée | kubectl get events --field-selector reason=Preempted | Baissez la valeur de la priority class ou ajustez le PodDisruptionBudget |
| Priority class introuvable | Inadéquation de nom ou confusion d'espace de noms (PriorityClass est à portée cluster) | kubectl get priorityclass <name> | Corrigez le manifeste et réappliquez |
Modes de défaillance et récupération
Même avec une planification minutieuse, des échecs surviennent. Concevez votre pipeline pour échouer bruyamment et récupérer rapidement.
Modes de défaillance courants
- Valeur invalide ou plage réservée : La valeur doit être un entier ≤ 1 000 000 000 pour les classes définies par l'utilisateur, sauf pour les classes système. L'application d'une valeur au-dessus de cette plage peut être rejetée.
- GlobalDefault dupliqué : Définir
globalDefault: truesur plus d'une classe casse l'ordonnancement du cluster ; Kubernetes peut refuser ou se comporter de manière imprévisible. - Mauvaise configuration RBAC : Le compte de service n'a pas la permission de mettre à jour les priority classes, provoquant l'échec du pipeline.
- Rejet par webhook : Un webhook d'admission personnalisé peut rejeter les changements de priority classes en fonction de la politique.
- Cascades de préemption : Augmenter trop une valeur de priorité peut provoquer l'éviction massive de pods de priorité inférieure, entraînant une interruption de service.
Récupération étape par étape
Scénario : La valeur d'une priority class a été trop augmentée, provoquant des évictions.
- Revenez immédiatement sur la priority class à sa valeur précédente en utilisant la sauvegarde ou le tag git :
kubectl apply -f priorityclasses-backup-20250101-120000.yaml
# Ou si vous utilisez git :
git checkout tags/priority-class-v1.1.0 -- priority-classes/base/
kubectl apply -f priority-classes/base/
- Vérifiez les pods affectés :
kubectl get pods -A -o wide | grep -i evicted
# Si les pods évincés ne redémarrent pas automatiquement (par exemple, s'ils ne sont pas gérés par un contrôleur), recréez-les.
- Vérifiez la stabilité du cluster en vérifiant la pression sur les ressources des nœuds et le journal des événements :
kubectl top nodes
kubectl get events --all-namespaces --sort-by=.lastTimestamp | tail -50
- Communiquez l'incident et mettez à jour la revue post-incident avec la chronologie et l'action corrective.
Retour arrière automatisé dans le pipeline
Pour automatiser le retour arrière, ajoutez une étape de pipeline qui s'exécute lorsque l'étape précédente échoue ou lorsqu'un retour arrière manuel est déclenché. Un script simple peut récupérer le manifeste précédent bon depuis l'historique git ou le magasin d'artefacts et l'appliquer.
Exemple d'étape de retour arrière de pipeline (GitLab CI) :
rollback:
stage: rollback
when: manual
script:
- git fetch --tags
- git checkout $PREVIOUS_TAG
- kubectl apply -f priority-classes/base/
environment:
name: production
action: rollback
L'opérateur saisit le tag précédent (par exemple, priority-class-v1.1.0) lors du déclenchement du job manuel.
Prévention des récidives
- Testez les changements dans un cluster de staging avec des définitions de priority class identiques avant la production.
- Limitez qui peut approuver les changements de priority class ; exigez deux revues si la valeur dépasse un seuil (par exemple, > 10000).
- Utilisez des moteurs de politique comme Kyverno ou OPA Gatekeeper pour appliquer des plages autorisées et empêcher les changements accidentels de valeur par défaut globale.
Exemple de politique Kyverno pour restreindre les valeurs de priorité définies par l'utilisateur :
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-priorityclass-values
spec:
validationFailureAction: Enforce
rules:
- name: check-value-range
match:
resources:
kinds:
- PriorityClass
validate:
message: "La valeur de PriorityClass doit être comprise entre -10 et 10000"
pattern:
value: "-10-10000"
Liste de contrôle des opérations
Utilisez cette liste avant, pendant et après chaque changement de priority class dans votre pipeline CI/CD. Remplissez les valeurs pour votre environnement.
Liste avant changement
- [ ] Version du cluster vérifiée :
kubectl version --shortmontre serveur >= 1.14 (ou version d'API ajustée). - [ ] Priority classes existantes listées et enregistrées avec valeurs et valeurs par défaut.
- [ ] Sauvegardes prises :
kubectl get priorityclass -o yaml > backup-$(date +%s).yamlet stockées. - [ ] Le compte de service RBAC
priority-class-deployera les permissions appropriées ; le jeton n'est pas expiré. - [ ] Le manifeste souhaité est dans git, revu et tagué.
- [ ] Essai à vide réussi à la fois côté client et serveur :
kubectl apply --dry-run=server -f <manifest>. - [ ] Plan de retour arrière défini : tag git précédent ou fichier de sauvegarde identifié.
Liste pendant le changement
- [ ] Pipeline déclenché et étapes de lint/diff réussies.
- [ ] Approbation manuelle obtenue (si nécessaire).
- [ ] Étape d'application exécutée avec succès avec journaux capturés.
- [ ] Commandes de vérification post-application exécutées, et la sortie correspond aux valeurs attendues.
Liste après changement
- [ ]
kubectl get priorityclass <name> -o yamlmontre lavalueet leglobalDefaultsouhaités. - [ ] Aucun événement de préemption inattendu :
kubectl get events --field-selector reason=Preemptedrenvoie vide ou seulement des événements attendus. - [ ] Les pods critiques avec la priority class modifiée sont en cours d'exécution et prêts (Ready).
- [ ] Les tableaux de bord de surveillance ne montrent aucune augmentation des pods non ordonnançables ou des évictions.
- [ ] Enregistrement du changement mis à jour dans votre base de données de gestion de configuration ou wiki.
- [ ] En cas d'échec, le retour arrière a été exécuté et vérifié.
Conclusion
Automatiser les changements de Priority Classes Kubernetes avec CI/CD n'est pas seulement une question de commodité ; il s'agit de rendre un paramètre de cluster à fort impact visible, reproductible et réversible. Les étapes pratiques de ce guide — inventorier votre environnement, verrouiller le chemin sûr avec des essais à vide et RBAC, vérifier chaque changement avec des commandes concrètes et répéter la récupération en cas d'échec — forment une boucle opérationnelle complète.
Commencez par un changement de priority class à faible risque : choisissez une classe qui affecte un seul déploiement non critique, faites-le passer par votre pipeline de git à l'application, et observez les sorties de vérification. Ensuite, étendez-vous à des classes plus critiques à mesure que votre confiance grandit.
Un flux de travail d'automatisation fiable pour l'ordonnancement Kubernetes garantit que les erreurs sont détectées avant qu'elles ne deviennent des pannes, et que la récupération est une action planifiée, pas une panique.