E-NO
Kubernetes 8 min de lecture

Affinité de nœud Kubernetes : erreurs courantes, correctifs et exemples pratiques

calendar_today Publié : 2026-08-20
update Dernière mise à jour : 2026-08-20
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Affinité de nœud Kubernetes : erreurs courantes, correctifs et exemples pratiques ».

Introduction

L'affinité de nœud Kubernetes vous offre un contrôle précis sur l'ordonnancement des pods en déclarant des règles qui attirent les pods vers des nœuds spécifiques. Lorsque ces règles sont mal configurées ou mal comprises, les pods peuvent rester en état Pending, être expulsés de manière inattendue ou atterrir sur le mauvais matériel. Cet article passe en revue les erreurs d'affinité de nœud les plus courantes, comment les diagnostiquer avec des commandes concrètes et comment les corriger avec des exemples pratiques.

Vous apprendrez à distinguer requiredDuringSchedulingIgnoredDuringExecution de preferredDuringSchedulingIgnoredDuringExecution, à lire les événements du planificateur avec kubectl describe pod, et à corriger les inadéquations d'étiquettes, les opérateurs invalides et les erreurs de clé de topologie. Chaque correctif inclut des extraits de manifeste à copier-coller et des étapes de vérification pour appliquer la solution en toute sécurité dans un espace de noms de développement avant de la déployer en production.

Inventaire des versions et de l'environnement

Avant de modifier un manifeste, confirmez la version de Kubernetes et les nœuds du cluster. La syntaxe de l'affinité de nœud est stable dans les versions récentes, mais le comportement des étiquettes et les messages du planificateur peuvent varier légèrement selon la version. Exécutez :

kubectl version --short
kubectl get nodes --show-labels

La sortie attendue comprend une ligne de version du serveur comme Server Version: v1.28.2 et une liste de nœuds avec leurs étiquettes. Par exemple :

NAME       STATUS   ROLES           AGE   VERSION   LABELS
node-1     Ready    control-plane   10d   v1.28.2   kubernetes.io/hostname=node-1,disktype=ssd,region=us-east
node-2     Ready    <none>          10d   v1.28.2   kubernetes.io/hostname=node-2,disktype=hdd,region=us-west

Si votre cluster est géré (EKS, GKE, AKS), utilisez l'interface de ligne de commande du fournisseur de cloud pour vérifier la version du plan de contrôle, mais les étiquettes des nœuds restent visibles via kubectl. Notez les clés et valeurs d'étiquettes exactes que vous prévoyez d'utiliser dans votre règle d'affinité. Une erreur courante consiste à supposer qu'une étiquette existe alors qu'elle n'existe pas. Avant d'ajouter disktype: ssd à votre affinité, vérifiez qu'au moins un nœud possède effectivement cette étiquette :

kubectl get nodes -l disktype=ssd

Aucune sortie ne signifie qu'aucun nœud ne correspond, et toute règle requiredDuringSchedulingIgnoredDuringExecution utilisant cette étiquette ne planifiera jamais.

Question rapide 1 sur 2

Quelle est la principale différence entre requiredDuringSchedulingIgnoredDuringExecution et preferredDuringSchedulingIgnoredDuringExecution dans node affinity ?

Selon la référence, requiredDuringSchedulingIgnoredDuringExecution signifie que le scheduler ne peut pas planifier le Pod à moins que la règle soit respectée, tandis que preferredDuringSchedulingIgnoredDuringExecution signifie que le scheduler essaie de trouver un nœud correspondant mais planifiera quand même le Pod si aucun n'est trouvé.

Chemin de configuration sécurisé

Testez toujours les modifications d'affinité dans un espace de noms hors production d'abord. Le plus petit test sûr est un pod unique avec une règle d'affinité simple qui reflète votre logique de production prévue. Par exemple :

apiVersion: v1
kind: Pod
metadata:
  name: affinity-test
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
  containers:
  - name: nginx
    image: nginx:1.25

Appliquez-le et vérifiez immédiatement l'état du pod :

kubectl apply -f affinity-test.yaml
kubectl get pod affinity-test -o wide

Si le pod est planifié et s'exécute sur un nœud avec disktype=ssd, votre règle fonctionne. S'il est en Pending, exécutez kubectl describe pod affinity-test et consultez la section Events :

Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  10s   default-scheduler  0/2 nodes are available: 2 node(s) didn't match node selector.

Ce message confirme que la règle d'affinité a exclu tous les nœuds. Corrigez l'étiquette ou la règle avant de continuer.

Vérification et diagnostics

Le diagnostic des échecs d'affinité de nœud nécessite d'examiner le processus de décision du planificateur. Commencez par les événements du pod, puis inspectez les étiquettes des nœuds et l'expression d'affinité elle-même.

Étape 1 : Décrire le pod en attente

kubectl describe pod <nom-du-pod>

Recherchez les événements FailedScheduling. Ils vous indiqueront pourquoi aucun nœud ne correspondait. Par exemple :

0/3 nodes are available: 1 node(s) had untolerated taint {dedicated: infrastructure}, 2 node(s) didn't match node affinity/selector.

Cela sépare les problèmes de teinture des problèmes d'affinité. Si les teintures sont le problème, vous avez besoin de tolérances, pas de modifications d'affinité. Si l'affinité est le problème, passez à la vérification des étiquettes.

Étape 2 : Vérifier les étiquettes des nœuds existants

kubectl get nodes --show-labels | grep disktype

Si aucune sortie, la clé d'étiquette n'existe sur aucun nœud. Ajoutez-la aux nœuds appropriés :

kubectl label node node-1 disktype=ssd

Puis vérifiez :

kubectl get node node-1 --show-labels

Sortie partielle attendue :

... disktype=ssd

Étape 3 : Valider l'expression d'affinité

Les erreurs courantes incluent :

  • Utiliser operator: Equal avec plusieurs valeurs (invalide ; Equal accepte exactement une valeur).
  • Utiliser operator: In mais laisser values vide.
  • Mal orthographier requiredDuringSchedulingIgnoredDuringExecution ou matchExpressions.
  • Oublier que nodeSelectorTerms est un tableau et doit contenir au moins un élément.

Par exemple, cet extrait invalide :

matchExpressions:
- key: disktype
  operator: Equal
  values: [ssd, nvme]

sera rejeté par le serveur API avec une erreur comme :

The Deployment "my-deploy" is invalid: spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms[0].matchExpressions[0].values: Invalid value: []string{"ssd", "nvme"}: must be a single value for Equal operator

Corrigez en utilisant operator: In avec plusieurs valeurs ou Equal avec une seule valeur.

Étape 4 : Surveiller le planificateur en temps réel

Si le pod reste en attente, surveillez les événements :

kubectl get events --field-selector involvedObject.name=<nom-du-pod> --watch

Cela diffuse les messages du planificateur à mesure que des nœuds deviennent disponibles ou que les étiquettes changent. Cela aide à confirmer que votre correctif a pris effet sans attendre le prochain cycle de nouvelle tentative.

Question rapide 2 sur 2

Laquelle des listes d'opérateurs suivantes peut être utilisée dans les matchExpressions de node affinity ?

La référence indique : « Vous pouvez utiliser `In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt` et `Lt`. »

Modes de défaillance et récupération

L'affinité de nœud peut échouer de plusieurs manières prévisibles. Chacune a une signature et une procédure de récupération spécifiques.

Défaillance 1 : Aucun nœud ne satisfait l'affinité requise

Symptôme : Pod bloqué en Pending. Les événements montrent 0/N nodes are available: N node(s) didn't match node affinity/selector.

Cause : La règle requiredDuringSchedulingIgnoredDuringExecution est trop stricte ou les étiquettes manquent.

Récupération :

  1. Vérifiez les étiquettes des nœuds avec kubectl get nodes --show-labels.
  2. Ajoutez les étiquettes manquantes à au moins un nœud.
  3. Ou modifiez l'affinité pour être moins restrictive, par exemple, changez required... en preferred... si l'exigence n'est pas absolument obligatoire.

Exemple de règle preferredDuringSchedulingIgnoredDuringExecution qui peut remplacer une règle required :

affinity:
  nodeAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      preference:
        matchExpressions:
        - key: disktype
          operator: In
          values:
          - ssd

Cela permet l'ordonnancement sur des nœuds sans disktype=ssd si aucun n'est disponible, mais les préfère lorsqu'ils sont présents.

Défaillance 2 : Pod planifié sur le mauvais nœud car la règle préférée a ignoré d'autres contraintes

Symptôme : Le pod s'exécute mais sur un nœud qui viole une attente métier.

Cause : Les règles preferred sont souples. Le planificateur peut les ignorer si des contraintes strictes (comme les demandes de ressources) forcent un placement différent.

Récupération : Convertissez la règle préférée en requise, ou ajoutez des règles requises supplémentaires. Vérifiez avec kubectl get pod -o wide pour voir le nœud.

Défaillance 3 : Le planificateur plante ou devient indisponible

Symptôme : Tous les pods en attente ne montrent aucun événement, ou kubectl describe pod ne montre aucun événement FailedScheduling mais le pod reste en attente.

Cause : Le pod du planificateur est arrêté ou ne fonctionne pas.

Récupération : Vérifiez la santé du planificateur :

kubectl get pods -n kube-system | grep scheduler
kubectl logs -n kube-system kube-scheduler-<nœud-du-plan-de-contrôle> --tail=50

Si le planificateur est sain, le problème est ailleurs (par exemple, pas de ressources). S'il est arrêté, redémarrez-le ou enquêtez sur le nœud sous-jacent.

Défaillance 4 : Conflit entre l'affinité de nœud et le sélecteur de nœud

Symptôme : Pod en attente malgré des nœuds qui semblent correspondre.

Cause : Vous avez défini à la fois nodeSelector et nodeAffinity. Le planificateur combine toutes les contraintes par ET logique, donc une inadéquation dans l'un ou l'autre empêche l'ordonnancement.

Récupération : Supprimez l'un ou rendez-les cohérents. Vérifiez la spécification complète du pod :

kubectl get pod <nom> -o yaml | grep -A5 nodeSelector

Puis alignez les étiquettes.

Liste de contrôle opérationnelle

Utilisez cette liste avant et après l'application des modifications d'affinité de nœud pour minimiser les risques.

Avant le changement

  • [ ] Exécutez kubectl get nodes --show-labels et enregistrez l'ensemble des étiquettes.
  • [ ] Identifiez au moins un nœud qui correspond à votre règle d'affinité prévue.
  • [ ] Confirmez que la version de Kubernetes prend en charge votre syntaxe d'affinité (toutes les versions stables le font, mais vérifiez si vous utilisez des fonctionnalités bêta).
  • [ ] Sauvegardez la spécification actuelle du déploiement/pod : kubectl get deploy my-deploy -o yaml > deploy-backup.yaml.
  • [ ] Testez la nouvelle règle d'affinité avec un pod minimal dans un espace de noms de développement.
  • [ ] Assurez-vous d'avoir la permission d'étiqueter les nœuds si votre correctif nécessite des modifications d'étiquettes.

Après le changement

  • [ ] Appliquez le manifeste modifié et surveillez le déploiement : kubectl rollout status deployment/my-deploy.
  • [ ] Vérifiez le placement des pods : kubectl get pods -o wide montre le nœud attendu.
  • [ ] Vérifiez les événements pour les erreurs d'ordonnancement : kubectl describe pod <nouveau-pod>.
  • [ ] Si le pod est en attente, capturez le message du planificateur avant de revenir en arrière.
  • [ ] Documentez le correctif et les modifications d'étiquettes dans votre runbook.

Exemple de déploiement complet avec affinité de nœud après un correctif :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: topology.kubernetes.io/zone
                operator: In
                values:
                - us-east-1a
                - us-east-1b
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 80
            preference:
              matchExpressions:
              - key: disktype
                operator: In
                values:
                - ssd
      containers:
      - name: nginx
        image: nginx:1.25

Cela exige que les pods s'exécutent dans les zones us-east-1a ou us-east-1b, et préfère les nœuds avec disktype=ssd. Vérifiez avec :

kubectl apply -f web-deploy.yaml
kubectl get pods -o wide

Tous les pods doivent être en état Running et leur colonne NODE doit montrer des nœuds dans les zones autorisées.

Conclusion

Les erreurs d'affinité de nœud sont presque toujours visibles dans les événements du pod, et le correctif implique généralement d'aligner les étiquettes avec vos expressions d'affinité. En suivant les étapes de diagnostic de cet article — vérifiez d'abord les étiquettes, validez ensuite la syntaxe de l'affinité, puis surveillez le planificateur — vous pouvez résoudre la plupart des problèmes en quelques minutes.

Rappelez-vous que requiredDuringSchedulingIgnoredDuringExecution est une contrainte stricte : si aucun nœud ne correspond, le pod ne sera jamais planifié. Utilisez preferredDuringSchedulingIgnoredDuringExecution pour des préférences souples qui ne doivent pas bloquer l'ordonnancement. Testez toujours dans un espace de noms de développement, conservez une sauvegarde de votre manifeste d'origine et documentez tout changement d'étiquette.

Un flux de travail fiable rend les échecs visibles, protège les valeurs sensibles et définit la vérification de la récupération avant qu'un incident ne force la décision. Avec les exemples pratiques présentés ici, vous pouvez aborder la configuration et le dépannage de l'affinité de nœud avec confiance.

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