Introduction
Le framework de planification Kubernetes est un puissant mécanisme d'extension qui permet à une logique personnalisée d'influencer le placement des pods. Bien qu'il offre une grande flexibilité, le dépannage des défaillances liées au framework peut s'avérer difficile. Ce guide propose une approche pratique pour diagnostiquer et résoudre les problèmes courants à l'aide de journaux, de commandes et de procédures de récupération.
Comprendre les composants du framework et leurs interactions est essentiel pour un dépannage efficace. En suivant les étapes décrites ici, vous pourrez identifier rapidement les causes profondes et appliquer des correctifs en toute sécurité. L'accent est mis sur des techniques pratiques et concrètes qui fonctionnent dans des clusters réels.
Une approche systématique permet de gagner du temps et de réduire le risque de mauvaise configuration. Nous aborderons l'inventaire de l'environnement, la configuration sécurisée, la vérification, les modes de défaillance et une liste de contrôle opérationnelle. Chaque section comprend des exemples concrets pour illustrer les points clés.
Inventaire de la version et de l'environnement
Avant de procéder au dépannage, recueillez des informations précises sur la version de votre cluster, sa topologie et la configuration du planificateur. Cette base de référence permet d'identifier les bogues spécifiques à une version ou les mauvaises configurations.
Prérequis
- Accès au cluster avec kubectl et autorisations pour consulter les journaux et la configuration du planificateur.
- Connaissance de la version et de la distribution de Kubernetes.
- Compréhension de la version du framework de planification utilisée, car le comportement peut changer d'une version à l'autre.
Exemple : collecte d'informations sur l'environnement
Exécutez les commandes suivantes pour capturer les détails essentiels :
kubectl version --client
kubectl get nodes -o wide
kubectl describe pod <nom-du-pod> -n <espace-de-noms>
La sortie attendue comprend les versions client et serveur, les statuts et étiquettes des nœuds, ainsi que les événements du pod. Par exemple, la description du pod peut montrer des échecs de planification avec des raisons telles que FailedScheduling. Voici un exemple de ce à quoi pourrait ressembler la sortie de kubectl get nodes -o wide :
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
node1 Ready master 10d v1.28.3 192.168.1.10 <none> Ubuntu 22.04.3 LTS 5.15.0-91-generic containerd://1.7.8
node2 Ready <none> 10d v1.28.3 192.168.1.11 <none> Ubuntu 22.04.3 LTS 5.15.0-91-generic containerd://1.7.8
node3 Ready <none> 10d v1.28.3 192.168.1.12 <none> Ubuntu 22.04.3 LTS 5.15.0-91-generic containerd://1.7.8
Informations clés à enregistrer
- Version du plan de contrôle Kubernetes (par exemple, v1.28.3)
- Version de l'image du planificateur et plugins personnalisés éventuels
- Étiquettes des nœuds, marques de non-tolérance (taints) et ressources
- Spécifications des pods, y compris les affinités, anti-affinités et contraintes de répartition topologique
Cet inventaire sert de point de référence pour comparer le comportement après des modifications. Stockez ces informations dans un document partagé ou un runbook à la disposition de l'équipe.
Chemin de configuration sécurisé
Lors de la modification de la configuration du planificateur, adoptez une approche limitée et réversible. Évitez d'apporter des changements étendus sans test, car ils peuvent perturber la planification sur l'ensemble du cluster.
Commencer par un pilote
Le premier pilote utile doit être restreint, mesurable et facile à inspecter localement. Par exemple, activez un plugin de notation personnalisé uniquement pour un espace de noms ou un type de charge de travail spécifique à l'aide d'un profil de planificateur.
Exemple : définition d'un profil de planificateur
Créez une ConfigMap avec une politique de planificateur incluant un plugin personnalisé pour un espace de noms de test :
apiVersion: v1
kind: ConfigMap
metadata:
name: my-scheduler-config
namespace: kube-system
data:
scheduler-config.yaml: |
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: my-scheduler
plugins:
score:
enabled:
- name: MyCustomScorer
pluginConfig:
- name: MyCustomScorer
args:
customParam: valeur
Appliquez la ConfigMap, puis créez des pods en spécifiant schedulerName: my-scheduler pour tester le chemin personnalisé sans affecter la planification par défaut.
Validation avant déploiement
Utilisez kubectl apply --dry-run=client pour valider la syntaxe YAML, et envisagez d'utiliser un cluster de préproduction pour une validation complète. Sauvegardez toujours la configuration existante du planificateur avant d'appliquer des modifications. Par exemple :
kubectl get configmap my-scheduler-config -n kube-system -o yaml > my-scheduler-config-backup.yaml
Cette sauvegarde permet une restauration rapide si la nouvelle configuration provoque des problèmes.
Vérification et diagnostic
Une vérification efficace repose sur l'observation du comportement du planificateur à travers les journaux, les événements et les métriques. Cette section couvre les commandes de diagnostic clés et les résultats attendus.
Consultation des journaux du planificateur
Accédez aux journaux du planificateur pour voir l'activité des plugins du framework. Si le planificateur s'exécute en tant que pod statique, utilisez :
kubectl logs -n kube-system <nom-du-pod-planificateur>
Recherchez les lignes indiquant l'exécution des plugins, telles que Running Score plugin, ou des erreurs comme failed to score pod. Exemple de ligne de journal pour un plugin de notation réussi :
I0321 10:00:00.123456 1 schedule_one.go:254] \"Scoring pod\" pod=\"default/test-pod\" plugin=\"MyCustomScorer\" score=80
Si le planificateur n'est pas un pod statique mais un déploiement, vous devrez peut-être consulter les journaux des pods du déploiement. Pour obtenir le nom du pod du planificateur, exécutez d'abord :
kubectl get pods -n kube-system -l component=kube-scheduler
Événements de pod
Les événements fournissent des indices initiaux sur les échecs de planification.
kubectl describe pod <nom-du-pod> -n <espace-de-noms>
Exemple d'événement :
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 10s default-scheduler 0/3 nœuds sont disponibles : 1 nœud(s) avait une marque de non-tolérance {clé: valeur}, que le pod ne tolérait pas, 2 Insuffisant cpu.
Cela indique des marques de non-tolérance et des pénuries de ressources. Pour voir tous les événements d'un espace de noms, utilisez :
kubectl get events -n <espace-de-noms> --sort-by=.lastTimestamp
Métriques de performance du planificateur
Si les métriques sont activées (par exemple, via --bind-address et le scraping Prometheus), interrogez les durées des tentatives de planification et les latences des plugins.
curl -s http://<ip-du-planificateur>:10251/metrics | grep scheduler_plugin_execution_duration
Des latences élevées dans les plugins personnalisés peuvent indiquer des problèmes de performance. Par exemple, si le 99e centile d'un plugin dépasse 100 ms, cela peut entraîner des retards de planification. Envisagez d'utiliser un outil comme kube-state-metrics pour collecter ces métriques dans Prometheus à des fins d'alerte.
Simulation et essai à vide
Kubernetes ne fournit pas de fonction d'essai à vide intégrée pour la planification, mais vous pouvez utiliser le binaire kube-scheduler localement avec un pod et un ensemble de nœuds simulés pour tester le comportement des plugins. C'est une technique avancée mais utile pour un débogage isolé. Une approche de base consiste à exécuter le planificateur avec une configuration de test sur un faux clientset. Exemple utilisant scheduler-simulator (un outil tiers) :
git clone https://github.com/kubernetes-sigs/scheduler-simulator
cd scheduler-simulator
make build
./bin/scheduler-simulator --config test-config.yaml
Créez ensuite un pod simulé et observez quels nœuds sont sélectionnés. Cela permet de valider la logique des plugins sans affecter un cluster réel.
Modes de défaillance et récupération
Les modes de défaillance courants incluent une mauvaise configuration des plugins, une contention des ressources et une incompatibilité de version. Cette section décrit les symptômes, les causes profondes et les étapes de récupération.
Arguments de plugin mal configurés
Si un plugin attend une structure d'argument spécifique et qu'elle est absente, le planificateur peut planter ou ne pas parvenir à planifier les pods. Vérifiez les journaux pour des erreurs comme invalid plugin config et comparez avec la documentation du plugin.
Récupération : Corrigez la ConfigMap et redémarrez le planificateur.
kubectl edit configmap my-scheduler-config -n kube-system
# Corrigez le YAML
kubectl delete pod <nom-du-pod-planificateur> -n kube-system # pour redémarrer si pod statique
Pour un pod statique, le kubelet le redémarrera automatiquement après la modification du manifeste. Si le planificateur est un déploiement, redémarrez le déploiement :
kubectl rollout restart deployment kube-scheduler -n kube-system
Pénurie de ressources sur les nœuds
Lorsque les pods restent à l'état Pending en raison d'un manque de CPU ou de mémoire, le planificateur ne peut pas les placer. Utilisez kubectl describe nodes pour vérifier la capacité et les allocations.
kubectl describe node node1
Recherchez la section Allocated resources :
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 1500m (75%) 0 (0%)
memory 2Gi (50%) 4Gi (100%)
Cela montre que le CPU est demandé à 75 %, il ne reste donc que 25 %. Si un pod a besoin de 500m de CPU, il peut encore tenir, mais s'il en a besoin de plus, il échouera.
Récupération : Ajoutez des nœuds, réduisez d'autres charges de travail ou ajustez les demandes de ressources du pod.
Incompatibilité de version
Les plugins personnalisés compilés contre une version différente de Kubernetes peuvent échouer. Assurez-vous que l'image du plugin et la version du planificateur sont compatibles.
Récupération : Reconstruisez le plugin avec la version correcte ou revenez à une configuration précédente du planificateur. Pour vérifier la version du planificateur :
kubectl exec -n kube-system <nom-du-pod-planificateur> -- kube-scheduler --version
Cela devrait afficher la version. Vérifiez ensuite la matrice de compatibilité du plugin.
Procédure de restauration
Si une modification du planificateur provoque des problèmes généralisés, revenez à la configuration précédente. Pour les pods statiques, le manifeste du planificateur se trouve généralement dans /etc/kubernetes/manifests/ sur le plan de contrôle. Restaurez la sauvegarde et le kubelet redémarrera le planificateur automatiquement.
Exemple de sauvegarde et de restauration :
sudo cp /etc/kubernetes/manifests/kube-scheduler.yaml /tmp/kube-scheduler.yaml.bak
# Apportez des modifications, puis pour restaurer :
sudo cp /tmp/kube-scheduler.yaml.bak /etc/kubernetes/manifests/kube-scheduler.yaml
Pour un planificateur non statique (par exemple, déployé en tant que Deployment), annulez le déploiement :
kubectl rollout undo deployment kube-scheduler -n kube-system
Vérification après récupération
Après la restauration, surveillez la planification des pods et les journaux pour confirmer un comportement normal. Créez un pod de test et assurez-vous qu'il est planifié dans un délai raisonnable :
kubectl run test-pod --image=nginx
kubectl get pod test-pod -w
Vérifiez que le pod passe à l'état Running en quelques minutes.
Liste de contrôle opérationnelle
Utilisez cette liste pour les vérifications de routine et la validation après modification.
| Étape | Action | Résultat attendu |
|---|---|---|
| 1 | Vérifier que le pod du planificateur est en cours d'exécution et prêt | kubectl get pods -n kube-system | grep scheduler affiche 1/1 Running |
| 2 | Vérifier les journaux récents du planificateur pour détecter des erreurs | Aucun motif d'erreur répété |
| 3 | Inspecter les pods en attente et leurs événements | Les événements montrent des tentatives de planification ou leur absence |
| 4 | Valider les ressources et les marques de non-tolérance des nœuds | Les nœuds ont une capacité suffisante ; les marques de non-tolérance sont tolérées par les charges de travail |
| 5 | Examiner la configuration du planificateur | Les paramètres de la ConfigMap ou des indicateurs correspondent aux valeurs prévues |
| 6 | Tester un pod canari après toute modification | Le pod est planifié dans le délai prévu et sur les bons nœuds |
| 7 | Surveiller les métriques du planificateur pour détecter des anomalies | La latence reste dans la plage de base ; aucune pointe soudaine |
Effectuez cette liste de contrôle avant et après tout changement important, et périodiquement pendant les opérations normales. Par exemple, exécutez-la chaque semaine dans le cadre des contrôles de santé du cluster.
Conclusion
Le dépannage du framework de planification Kubernetes nécessite une approche systématique. En collectant des données sur l'environnement, en apportant des modifications de configuration limitées, en vérifiant via les journaux et les événements, et en disposant d'un plan de récupération solide, vous pouvez résoudre les problèmes efficacement.
N'oubliez pas de commencer petit, de valider soigneusement et de toujours conserver des sauvegardes. La liste de contrôle opérationnelle fournie constitue un outil pratique pour la maintenance continue.
Comme prochaines étapes, envisagez d'activer une journalisation plus détaillée du planificateur pour les problèmes persistants, d'explorer les métriques pour l'optimisation des performances et de partager les leçons apprises avec votre équipe pour améliorer la fiabilité de la planification. Par exemple, vous pouvez créer un runbook qui documente chaque incident, la cause profonde et la résolution, afin que l'équipe capitalise les connaissances et réduise le temps moyen de récupération.