Intro
Le dépannage du planificateur Kube peut ressembler à chercher une aiguille dans une botte de foin : les pods restent en attente (Pending), les nœuds sont inactifs et les journaux offrent des indices énigmatiques. Ce guide change la donne. Il s'agit d'un parcours pratique, éprouvé sur le terrain, destiné aux développeurs, consultants DevOps et équipes techniques de startups qui doivent passer d'un problème observé à une correction vérifiée.
Vous apprendrez à identifier la version et la topologie de votre planificateur, à inspecter sa configuration en toute sécurité, à extraire des informations exploitables des journaux, à diagnostiquer les modes de défaillance courants et à appliquer des étapes de récupération en toute confiance. Chaque section comprend des commandes concrètes, les sorties attendues et les signaux d'échec afin de savoir si vous êtes sur la bonne voie.
L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier chaque résultat et documenter les chemins de récupération avant qu'un incident ne vous force la main.
Inventaire de version et d'environnement
Avant de toucher à kube-scheduler, sachez exactement à quoi vous avez affaire. Le planificateur est un composant du plan de contrôle qui peut s'exécuter en tant que pod statique, déploiement ou service systemd selon la méthode d'installation de Kubernetes. Sa version est importante car les drapeaux, les fichiers de configuration et le comportement de journalisation changent entre les versions.
Identifier la version du planificateur
Exécutez la commande suivante pour voir la version du planificateur et les informations de build :
kubectl version --short
La sortie attendue inclut les versions client et serveur, par exemple :
Client Version: v1.28.2
Server Version: v1.28.2
Si le planificateur s'exécute en tant que pod dans l'espace de noms kube-system, vous pouvez obtenir directement l'étiquette de son image :
kubectl get pod -n kube-system -l component=kube-scheduler -o jsonpath='{.items[0].spec.containers[0].image}'
Exemple de sortie :
registry.k8s.io/kube-scheduler:v1.28.2
Notez cette version. De nombreux guides de dépannage font référence à des drapeaux ou des clés de configuration qui diffèrent selon les versions, et utiliser la mauvaise peut vous induire en erreur.
Déterminer la topologie de déploiement
Comment le planificateur est-il déployé ? Vérifiez s'il s'agit d'un pod statique géré par le kubelet sur le nœud du plan de contrôle :
kubectl get pod -n kube-system -l component=kube-scheduler -o wide
Exemple de sortie :
NAME READY STATUS RESTARTS AGE IP NODE
kube-scheduler-master01 1/1 Running 0 5d 10.0.0.10 master01
Si vous voyez un pod mais qu'il n'est pas géré par un déploiement ou un ReplicaSet, il s'agit probablement d'un pod statique dont le manifeste réside dans /etc/kubernetes/manifests/kube-scheduler.yaml. Sinon, le planificateur peut s'exécuter en tant que service systemd sur le nœud du plan de contrôle :
systemctl status kube-scheduler
Sortie typique sur un nœud sain :
● kube-scheduler.service - Kubernetes Scheduler
Loaded: loaded (/etc/systemd/system/kube-scheduler.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2023-10-02 09:15:30 UTC; 1 day ago
Connaître la méthode de déploiement vous indique où chercher la configuration et les journaux. Les manifestes de pod statique et les fichiers d'unité systemd contiennent souvent des drapeaux qui remplacent les valeurs par défaut.
Vérifier la santé du planificateur
Un contrôle de santé rapide est l'endpoint /healthz du planificateur. Si vous avez accès au nœud du plan de contrôle, utilisez curl :
curl -k https://localhost:10259/healthz
Réponse attendue :
ok
Si le planificateur ne répond pas, le processus est peut-être arrêté, le port mal configuré ou les certificats TLS invalides. Vérifiez à nouveau l'état du pod :
kubectl get pod -n kube-system -l component=kube-scheduler
Un pod du planificateur bloqué en CrashLoopBackOff ou Error indique un problème sérieux. Récupérez la description du pod pour les événements :
kubectl describe pod -n kube-system -l component=kube-scheduler
Cherchez des événements comme Failed to start container ou MountVolume.SetUp failed. Ceux-ci pointent souvent vers des fichiers manquants ou des permissions incorrectes.
Observation en lecture seule d'abord
Commencez toujours par des commandes en lecture seule. Ne modifiez pas les manifestes et ne redémarrez pas les services tant que vous n'avez pas compris l'état actuel. Capturez les horodatages et les sorties dans un fichier journal pour comparaison ultérieure.
Chemin de configuration sûr
La configuration de Kube Scheduler est généralement définie par un fichier YAML passé via le drapeau --config, ou par un ensemble de drapeaux en ligne de commande. Modifier la configuration sans test peut casser la planification pour tout le cluster, alors procédez avec prudence.
Localiser la source de configuration
Si le planificateur s'exécute en tant que pod statique, visualisez son manifeste pour trouver le chemin du fichier de configuration et les drapeaux :
cat /etc/kubernetes/manifests/kube-scheduler.yaml
Cherchez des lignes comme :
spec:
containers:
- command:
- kube-scheduler
- --config=/etc/kubernetes/scheduler-config.yaml
Ou, si vous utilisez directement des drapeaux :
- --profiles=default-scheduler
- --leader-elect=true
Si le planificateur s'exécute en tant que service systemd, examinez le fichier d'unité :
systemctl cat kube-scheduler
La sortie peut montrer une ligne ExecStart :
ExecStart=/usr/local/bin/kube-scheduler \
--config=/etc/kubernetes/scheduler-config.yaml \
--v=2
Valider la configuration avant application
Avant tout changement, validez le fichier de configuration en utilisant le binaire du planificateur avec --config et un essai à blanc :
kube-scheduler --config=/etc/kubernetes/scheduler-config.yaml --dry-run
Si la configuration est valide, le planificateur démarrera et se fermera immédiatement en mode essai à blanc. Toute erreur est affichée sur stdout/stderr. Par exemple, une faute de frappe dans la version de l'API produirait :
error: error unmarshaling configuration: unknown field "apiVersion" in v1beta3.KubeSchedulerConfiguration
Corrigez alors le fichier avant application.
Faire un changement ciblé à la fois
Lors de l'édition de la configuration du planificateur, ne modifiez qu'un seul paramètre et gardez une sauvegarde du fichier original :
cp /etc/kubernetes/scheduler-config.yaml /etc/kubernetes/scheduler-config.yaml.bak
Par exemple, supposons que vous vouliez augmenter la verbosité de journalisation du planificateur au niveau débogage. Dans le fichier de configuration, vous pourriez éditer :
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
clientConnection:
kubeconfig: /etc/kubernetes/scheduler.conf
leaderElection:
leaderElect: true
profiles:
- schedulerName: default-scheduler
Ajoutez verbosity: 5 sous clientConnection ou définissez le drapeau --v=5 si vous utilisez des drapeaux. Après sauvegarde, redémarrez le processus du planificateur. Pour les pods statiques, le kubelet redémarre automatiquement les pods lorsque le manifeste change ; pour systemd, exécutez :
systemctl restart kube-scheduler
Vérifier le changement
Vérifiez que le planificateur fonctionne et journalise à la nouvelle verbosité :
kubectl logs -n kube-system -l component=kube-scheduler --tail=20
Vous devriez voir des lignes de journal plus détaillées, y compris les tentatives de planification pour chaque pod. Si le planificateur ne démarre pas, vérifiez les journaux pour les erreurs et revenez à la sauvegarde si nécessaire :
cp /etc/kubernetes/scheduler-config.yaml.bak /etc/kubernetes/scheduler-config.yaml
systemctl restart kube-scheduler
Définissez toujours à quoi ressemble une vérification réussie avant de faire le changement. Pour une augmentation de verbosité, le succès signifie plus d'entrées de journal sans erreurs, et le pod du planificateur affiche l'état Running.
Vérification et diagnostics
Diagnostiquer les problèmes du planificateur implique souvent de vérifier les événements des pods, les journaux du planificateur et l'état du cluster. Voici des étapes pratiques de diagnostic.
Vérifier les pods en attente
Identifiez les pods qui restent en état Pending parce qu'aucun nœud ne peut les satisfaire :
kubectl get pods --all-namespaces --field-selector=status.phase=Pending
Exemple de sortie :
NAMESPACE NAME READY STATUS RESTARTS AGE
default nginx-pod 0/1 Pending 0 10m
Décrivez un pod en attente pour voir les événements du planificateur :
kubectl describe pod nginx-pod
Cherchez des événements comme :
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 10m default-scheduler 0/3 nodes are available: 3 Insufficient cpu.
Cela indique clairement que le pod demande plus de CPU qu'aucun nœud ne peut fournir. Ajustez les demandes de ressources ou ajoutez des nœuds.
Examiner les journaux du planificateur
Les journaux du planificateur sont inestimables. Utilisez kubectl logs comme montré précédemment. Pour voir les journaux d'un pod de planificateur spécifique :
kubectl logs -n kube-system kube-scheduler-master01 --tail=50
Si le planificateur s'exécute en tant que service systemd, utilisez journalctl :
journalctl -u kube-scheduler -n 50 --no-pager
Cherchez les messages clés :
Successfully bound pod to nodeindique une décision de planification réussie.Error scheduling podavec une raison commenode(s) didn't match node selectorpointe vers des problèmes d'affinité/sélecteur de nœud.Unable to schedule pod; no fitsignifie qu'aucun nœud n'a satisfait tous les prédicats.
Utiliser le simulateur de planificateur (optionnel)
Pour les scénarios complexes, utilisez le simulateur autonome du planificateur (par exemple, kube-scheduler-simulator) dans un environnement de test. Il vous permet de fournir des spécifications de pod et un inventaire de nœuds pour voir les résultats de planification sans affecter la production.
Vous pouvez exécuter le simulateur en tant que conteneur :
docker run -p 3000:3000 ghcr.io/kubernetes-sigs/kube-scheduler-simulator:latest
Naviguez ensuite vers http://localhost:3000 et utilisez l'interface web pour créer des nœuds et des pods, et observez quels nœuds le planificateur choisirait.
Modes de défaillance et récupération
Modes de défaillance courants du planificateur et leurs étapes de récupération.
CrashLoopBackOff du pod du planificateur
Si le pod du planificateur plante à plusieurs reprises, vérifiez les journaux :
kubectl logs -n kube-system kube-scheduler-master01 --previous
Causes courantes :
- Fichier de configuration manquant ou malformé.
- Certificats TLS incorrects.
- Absence de permissions pour le kubeconfig du planificateur.
Exemple de récupération : si le chemin du fichier de configuration est incorrect, corrigez le manifeste et laissez le kubelet redémarrer automatiquement le pod. Ou, si le kubeconfig est invalide, régénérez-le avec kubeadm ou votre outil de cluster.
Problèmes d'élection de leader
Dans les configurations haute disponibilité, une seule instance du planificateur est active ; les autres attendent. Si l'élection de leader échoue, les pods du planificateur peuvent tous être en CrashLoopBackOff ou redémarrer fréquemment. Vérifiez les journaux pour les messages d'élection de leader :
kubectl logs -n kube-system kube-scheduler-master01 | grep -i leader
Attendez-vous à des lignes comme :
I1003 09:15:30.123456 1 leaderelection.go:258] successfully acquired lease kube-system/kube-scheduler
Si vous voyez des tentatives répétées d'acquisition du bail sans succès, vérifiez l'objet Lease de kube-scheduler :
kubectl get lease -n kube-system kube-scheduler -o yaml
Assurez-vous qu'il n'y a pas de détenteur périmé et que les endpoints sont joignables. Parfois, supprimer le bail aide s'il est bloqué :
kubectl delete lease -n kube-system kube-scheduler
N'utilisez ceci qu'en dernier recours et après en avoir compris les implications.
Ressources insuffisantes
Lorsque les pods ne peuvent pas être planifiés parce que les nœuds manquent de CPU, mémoire ou autres ressources, le planificateur émettra des messages Insufficient. Vérifiez la capacité des nœuds et les ressources allouables :
kubectl describe nodes
Cherchez les lignes sous Allocatable :
Allocatable:
cpu: 4
memory: 8Gi
ephemeral-storage: 100Gi
Comparez avec les demandes des pods. Si les demandes sont trop élevées, ajustez-les. Si les nœuds sont réellement pleins, ajoutez des nœuds ou réduisez d'autres charges de travail.
Inadéquation de sélecteur/affinité de nœud
Les pods avec des sélecteurs de nœud ou des règles d'affinité qui ne correspondent à aucun nœud resteront en attente. Exemple d'événement :
0/3 nodes are available: 3 node(s) didn't match node selector.
Vérifiez les étiquettes des nœuds :
kubectl get nodes --show-labels
Récupération : mettez à jour les étiquettes des nœuds si possible, ou modifiez le nodeSelector/affinité du pod pour correspondre aux nœuds réels. Par exemple, ajoutez une étiquette à un nœud :
kubectl label node worker01 disktype=ssd
Tolérances et marques (taints)
Les pods qui ne tolèrent pas les marques des nœuds n'y seront pas planifiés. Voyez les marques :
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
Si un nœud a une marque comme node-role.kubernetes.io/master:NoSchedule, les pods sans tolérances correspondantes l'ignoreront. Ajoutez des tolérances à la spécification du pod ou retirez la marque si approprié :
kubectl taint nodes master01 node-role.kubernetes.io/master:NoSchedule-
Soyez prudent lorsque vous retirez des marques sur les nœuds du plan de contrôle en production.
Liste de contrôle des opérations
Une liste de contrôle concise pour les opérations quotidiennes et le dépannage.
| Domaine | Action | Commande | Signal attendu |
|---|---|---|---|
| État du planificateur | Vérifier que le pod est en cours d'exécution | kubectl get pod -n kube-system -l component=kube-scheduler | READY 1/1, STATUS Running |
| Journaux | Voir les 50 dernières lignes | kubectl logs -n kube-system -l component=kube-scheduler --tail=50 | Pas de lignes d'erreur comme FailedScheduling |
| Pods en attente | Lister tous les pods Pending | kubectl get pods --all-namespaces --field-selector=status.phase=Pending | Aucun pod, ou Pending connu acceptable |
| Événements | Décrire un pod bloqué | kubectl describe pod <pod-name> | Les événements montrent une planification réussie ou une raison claire d'échec |
| Validation de configuration | Essai à blanc du planificateur avec config | kube-scheduler --config=/path/to/config --dry-run | Aucune sortie d'erreur |
| Endpoint de santé | Vérifier la santé du planificateur | curl -k https://localhost:10259/healthz | Renvoie ok |
| Élection de leader | Vérifier le détenteur du bail | kubectl get lease -n kube-system kube-scheduler -o yaml | L'identité du détenteur correspond à un pod en cours d'exécution |
Exécutez ces vérifications régulièrement ou lors du dépannage. Enregistrez toujours les sorties et horodatages pour l'audit et les décisions de retour en arrière.
Conclusion
Le dépannage du planificateur Kube est un processus systématique, pas une devinette. Commencez par l'inventaire de l'environnement pour connaître la version et la topologie. Inspectez la configuration en toute sécurité, en ne faisant qu'un seul changement à la fois avec validation et plans de retour en arrière. Utilisez les journaux et les événements de pod pour identifier les échecs, et appliquez des étapes de récupération spécifiques au mode de défaillance.
Comme prochaine étape, choisissez une vérification à faible risque de la liste de contrôle des opérations, exécutez-la sur votre cluster et comparez le résultat au signal attendu. Passez en revue les dépendances telles que le framework de planification, la priorité des pods et la préemption, et l'affinité de nœud lorsque c'est approprié.
Un flux de travail fiable rend la défaillance visible, 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.
Maîtrisez ces pratiques, et vous transformerez le dépannage du planificateur d'un exercice d'incendie en une procédure de routine et contrôlée.