## Introduction Les plugins de périphériques Kubernetes permettent aux pods d'accéder à du matériel spécialisé comme les GPU, FPGA et cartes réseau. Cependant, des erreurs de configuration peuvent entraîner des échecs de planification des pods, des blocages de ressources ou même des plantages de nœuds. Ce guide pratique s'adresse aux développeurs, aux consultants DevOps et aux équipes techniques de startups qui doivent configurer les plugins de périphériques en toute sécurité et résoudre rapidement les problèmes. Nous allons suivre une approche structurée : d'abord, faire un inventaire complet des versions et de l'environnement ; ensuite, appliquer des modifications de configuration en toute sécurité ; puis, vérifier et diagnostiquer les problèmes ; et enfin, gérer les modes de défaillance avec des procédures de récupération. Chaque section comprend des commandes concrètes, des sorties attendues et des exemples concrets. En suivant ce cadre de sécurité opérationnelle — observer avant de modifier, limiter le rayon d'impact, éviter les secrets codés en dur, vérifier les résultats et documenter les chemins de retour en arrière — vous réduirez les risques et les temps d'arrêt. ## Inventaire des versions et de l'environnement Avant de modifier toute configuration, vous devez comprendre votre cluster Kubernetes et l'écosystème des plugins de périphériques. Capturer les versions exactes, la topologie de déploiement et les prérequis évite les erreurs évitables. Commencez par des observations en lecture seule, enregistrez les horodatages et protégez les informations d'identification. ### Étape 1 : Collecter les informations sur le cluster et les nœuds Exécutez les commandes suivantes pour capturer l'état actuel : ```bash kubectl version --short kubectl get nodes -o wide kubectl get pods -n kube-system -l component=kubelet -o wide ``` La sortie attendue ressemble à : ```text Client Version: v1.27.3 Server Version: v1.27.3 NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME node-1 Ready control-plane 10d v1.27.3 10.0.0.10 Ubuntu 22.04.3 LTS 5.15.0-91-generic containerd://1.7.2 node-2 Ready 10d v1.27.3 10.0.0.11 Ubuntu 22.04.3 LTS 5.15.0-91-generic containerd://1.7.2 ``` **Points clés à vérifier :** - Version de Kubernetes : l'API des plugins de périphériques `v1beta1` a été dépréciée en 1.20 et supprimée en 1.25 ; seule la version `v1` est prise en charge dans les clusters modernes. Confirmez que le plugin est construit avec la bonne API. - Système d'exploitation et noyau du nœud : certains plugins nécessitent des modules de noyau ou des pilotes spécifiques (par exemple, le pilote NVIDIA pour GPU). - Runtime de conteneurs : les plugins interagissent avec le runtime via le mécanisme d'enregistrement des plugins de périphériques de la kubelet ; une incompatibilité peut entraîner des échecs d'enregistrement. ### Étape 2 : Inspecter les déploiements existants de plugins de périphériques Listez tous les pods dans `kube-system` et filtrez les noms de plugins de périphériques : ```bash kubectl get pods -n kube-system | grep -E 'device-plugin|nvidia|intel|amd|fpga|nic' ``` Exemple de sortie : ```text nvidia-device-plugin-daemonset-6xz7m 1/1 Running 0 3d ``` Si rien n'apparaît, vérifiez le DaemonSet : ```bash kubectl get ds -n kube-system | grep -i device ``` La sortie attendue pourrait montrer : ```text NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE nvidia-device-plugin 2 2 2 2 2 3d ``` Utilisez `kubectl describe ds -n kube-system` pour voir le modèle de pod, les demandes de ressources et les tolérances. ### Étape 3 : Vérifier les ressources allouables du nœud et le nombre de périphériques Vérifiez si le plugin a annoncé des périphériques à la kubelet : ```bash kubectl describe node | grep -A 10 'Allocatable' ``` Recherchez des ressources étendues comme `nvidia.com/gpu: 2` ou `amd.com/gpu: 1`. Si elles sont absentes, le plugin n'est pas sain ou n'est pas enregistré. ### Étape 4 : Examiner les journaux du plugin pour les erreurs de démarrage ```bash kubectl logs -n kube-system --tail=50 ``` Surveillez les messages comme : ```text I0628 10:00:00.123456 1 main.go:120] Starting FS watcher. I0628 10:00:00.234567 1 main.go:130] Starting OS watcher. E0628 10:00:00.345678 1 main.go:140] Failed to initialize NVML: could not load NVML library. ``` La dernière ligne indique un pilote manquant — une erreur courante. ## Chemin de configuration sûr Lorsque vous devez modifier la configuration du plugin de périphériques, adoptez une approche pas à pas qui minimise les risques. Appliquez une modification à la fois, validez dans un environnement de test si possible, et ayez toujours un plan de retour en arrière. ### Principe : moindre privilège et changement minimal Une erreur fréquente consiste à déployer une mise à jour de plugin sur tous les nœuds sans test. Au lieu de cela : 1. Choisissez un seul nœud ou un pool de nœuds non productif. 2. Étiquetez-le pour les tests : `kubectl label node node-1 test-device-plugin=true`. 3. Ajustez temporairement le sélecteur de nœud du DaemonSet à l'aide d'un patch ou d'un manifeste séparé. Exemple de patch pour cibler uniquement les nœuds avec l'étiquette `test-device-plugin=true` : ```yaml spec: template: spec: nodeSelector: test-device-plugin: "true" ``` Appliquez avec : ```bash kubectl patch ds nvidia-device-plugin -n kube-system --patch '{"spec":{"template":{"spec":{"nodeSelector":{"test-device-plugin":"true"}}}}}' ``` Attendez le déploiement et vérifiez l'état du pod : ```bash kubectl rollout status ds/nvidia-device-plugin -n kube-system ``` Sortie attendue : ```text daemon set "nvidia-device-plugin" successfully rolled out ``` En cas de succès, étendez progressivement l'étiquette aux autres nœuds. ### Utiliser des espaces réservés plutôt que des secrets Ne mettez jamais d'informations d'identification directement dans la configuration du plugin. Utilisez les Secrets Kubernetes et référencez-les via des variables d'environnement ou des volumes montés. Par exemple, si un plugin a besoin d'une clé de licence, créez un Secret : ```bash kubectl create secret generic device-plugin-license --from-literal=license-key='abc123' -n kube-system ``` Puis, dans le manifeste du DaemonSet : ```yaml env: - name: LICENSE_KEY valueFrom: secretKeyRef: name: device-plugin-license key: license-key ``` Évitez de coder en dur la clé dans la spécification du conteneur ; elle apparaît dans `kubectl describe` et les journaux. ### Exemple : mise à jour sécurisée de la version du plugin de périphériques NVIDIA Supposons que vous deviez passer de la version `v0.12.2` à `v0.14.0`. Étapes : 1. Sauvegardez le manifeste actuel : ```bash kubectl get ds nvidia-device-plugin -n kube-system -o yaml > nvidia-device-plugin-v0.12.2-backup.yaml ``` 2. Appliquez le nouveau manifeste avec la nouvelle image, mais uniquement au nœud de test (en utilisant le sélecteur d'étiquette). 3. Surveillez les journaux et l'état des ressources du nœud : ```bash kubectl logs -n kube-system -l name=nvidia-device-plugin-ds --tail=20 kubectl describe node node-1 | grep nvidia.com/gpu ``` 4. Si la nouvelle version échoue, revenez en arrière en réappliquant le manifeste de sauvegarde. 5. Une fois satisfait, supprimez le sélecteur de nœud pour déployer sur tout le cluster. ## Vérification et diagnostics Après les modifications de configuration, vérifiez que le plugin est sain et que les périphériques sont disponibles. Diagnostiquer les problèmes tôt permet d'économiser des heures de dépannage. ### Commandes de vérification **1. Vérifier l'état du DaemonSet** ```bash kubectl get ds -n kube-system | grep nvidia ``` Attendu : `DESIRED` est égal à `READY` et `AVAILABLE`. **2. Confirmer la santé du pod** ```bash kubectl get pods -n kube-system -l name=nvidia-device-plugin-ds -o wide ``` Recherchez `Running` et `Ready 1/1`. Si un pod n'est pas prêt, utilisez `kubectl describe pod -n kube-system` pour voir les événements. Recherchez `FailedScheduling`, `CrashLoopBackOff` ou `FailedMount`. **3. Valider l'enregistrement des périphériques sur le nœud** ```bash kubectl get node node-1 -o json | jq '.status.allocatable' ``` Si `nvidia.com/gpu` apparaît avec une valeur supérieure à 0, le plugin annonce des périphériques. **4. Tester la planification d'un pod avec une demande de GPU** Créez un pod de test qui demande un GPU : ```yaml apiVersion: v1 kind: Pod metadata: name: gpu-test-pod spec: restartPolicy: Never containers: - name: cuda-vector-add image: k8s.gcr.io/cuda-vector-add:v0.1 resources: limits: nvidia.com/gpu: 1 ``` Appliquez et vérifiez l'état : ```bash kubectl apply -f gpu-test-pod.yaml kubectl get pod gpu-test-pod ``` S'il reste `Pending`, inspectez les événements : ```bash kubectl describe pod gpu-test-pod ``` Recherchez les messages d'erreur comme `Insufficient nvidia.com/gpu` (aucun périphérique disponible) ou `Failed to allocate` (problème de plugin). ### Diagnostics pour les problèmes courants **Problème 1 : Pod en attente avec "Insufficient nvidia.com/gpu"** - Cause : le nœud n'a pas de GPU ou le plugin ne s'exécute pas. - Diagnostic : `kubectl get ds -n kube-system`, `kubectl logs -n kube-system `. - Correction : assurez-vous que le DaemonSet du plugin s'exécute sur le nœud et que le pilote est installé. **Problème 2 : CrashLoopBackOff du pod du plugin** - Cause : bibliothèque manquante, erreur de permission ou API incompatible. - Les journaux peuvent montrer : `Fatal: failed to start device plugin: rpc error: code = Unimplemented desc = unknown service v1beta1.DevicePlugin` (si vous utilisez une ancienne API sur une nouvelle kubelet). - Correction : utilisez une version de plugin compatible avec votre version de Kubernetes, ou mettez à jour `--device-plugin-version` (si pris en charge). **Problème 3 : Périphérique non visible dans Allocatable** - Cause : le plugin ne s'enregistre pas en raison d'un problème de chemin de socket. - Le plugin crée généralement une socket Unix à `/var/lib/kubelet/device-plugins/` ; assurez-vous que le DaemonSet monte ce répertoire avec `hostPath`. - Vérifiez les montages de volume dans la spécification du pod : ```yaml volumeMounts: - name: device-plugin mountPath: /var/lib/kubelet/device-plugins volumes: - name: device-plugin hostPath: path: /var/lib/kubelet/device-plugins ``` ## Modes de défaillance et récupération Même avec une planification minutieuse, des échecs surviennent. Connaître les modes de défaillance courants et avoir un plan de récupération réduit le temps moyen de réparation (MTTR). ### Mode de défaillance 1 : la mise à jour du plugin casse la découverte de périphériques **Scénario :** Vous avez mis à jour le plugin de la v1 à la v2, mais la v2 nécessite une version de pilote différente, ce qui fait planter le plugin au démarrage. **Récupération :** 1. Revenez immédiatement en arrière sur le DaemonSet à la version précédente : ```bash kubectl rollout undo ds/nvidia-device-plugin -n kube-system ``` Ou appliquez le manifeste de sauvegarde. 2. Vérifiez que les pods reviennent à l'état Running et que les périphériques réapparaissent : ```bash kubectl get pods -n kube-system -l name=nvidia-device-plugin-ds kubectl describe node node-1 | grep nvidia.com/gpu ``` ### Mode de défaillance 2 : limites de ressources mal configurées causant un blocage de planification **Scénario :** Vous avez configuré le plugin pour annoncer un nombre de périphériques supérieur à la réalité en modifiant le drapeau `--device-count`. Les pods sont planifiés mais échouent au démarrage. **Récupération :** 1. Corrigez le drapeau dans la spécification du DaemonSet et déployez : ```bash kubectl edit ds nvidia-device-plugin -n kube-system # changer --device-count=N au nombre réel ``` 2. Supprimez les pods bloqués ou laissez-les être évincés ; ils seront replanifiés avec les bons comptes. ### Mode de défaillance 3 : isolation et drainage du nœud pour la maintenance du plugin **Scénario :** Vous devez mettre à jour le pilote hôte (par exemple, le pilote NVIDIA) et devez drainer le nœud. **Étapes :** 1. Isolez le nœud : ```bash kubectl cordon node-1 ``` 2. Drainez les pods (mais pas les daemonsets par défaut ; incluez `--ignore-daemonsets`) : ```bash kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data ``` 3. Effectuez la maintenance (mise à jour du pilote, redémarrage). 4. Réactivez le nœud : ```bash kubectl uncordon node-1 ``` 5. Vérifiez que le pod du plugin redémarre et que les périphériques s'enregistrent. **Important :** Ayez toujours une sauvegarde récente du manifeste du DaemonSet et sachez comment revenir en arrière. ## Liste de contrôle opérationnelle Utilisez cette liste de contrôle avant et après toute modification de configuration de plugin de périphériques. Elle encapsule les meilleures pratiques pour éviter les erreurs courantes. ### Liste de contrôle avant modification | Élément | Commande / Vérification | Résultat attendu | |---------|-------------------------|------------------| | 1. Confirmer la version du cluster | `kubectl version --short` | Serveur >= 1.25 pour l'API v1 uniquement | | 2. Confirmer la compatibilité de version du plugin | Lire la documentation du plugin ou `kubectl describe ds -n kube-system` | La version du plugin prend en charge la version du cluster | | 3. Vérifier l'état des ressources du nœud | `kubectl describe node \| grep -A5 Allocatable` | Ressources étendues visibles si le plugin fonctionne | | 4. Sauvegarder le manifeste actuel | `kubectl get ds -n kube-system -o yaml > backup.yaml` | Fichier de sauvegarde créé | | 5. Étiqueter le nœud de test | `kubectl label node test-device-plugin=true` | Étiquette appliquée | | 6. S'assurer qu'aucun secret n'est codé en dur | `kubectl get ds -n kube-system -o yaml \| grep -i secret` | Seulement des références à des objets Secret | ### Liste de contrôle après modification | Élément | Commande / Vérification | Résultat attendu | |---------|-------------------------|------------------| | 1. État du déploiement du DaemonSet | `kubectl rollout status ds/ -n kube-system` | "successfully rolled out" | | 2. Santé du pod | `kubectl get pods -n kube-system -l name=<étiquette-du-plugin>` | Running et Ready 1/1 | | 3. Enregistrement des périphériques | `kubectl describe node \| grep ` | Compte de ressources étendues > 0 | | 4. Test de planification de pod | Appliquer un pod de test demandant un périphérique ; vérifier l'état | Le pod devient Running ou se termine | | 5. Vérification des journaux | `kubectl logs -n kube-system --tail=50` | Aucune erreur fatale | | 6. Procédure de retour en arrière documentée | Avoir la commande `kubectl rollout undo` prête | Pouvoir revenir rapidement | Exemple de liste de contrôle remplie pour une mise à jour fictive du plugin NVIDIA : - Étiquette du nœud de test : `node-1` étiqueté `test-device-plugin=true`. - Fichier de sauvegarde : `nvidia-device-plugin-v0.12.2-backup.yaml` enregistré. - Après modification : `nvidia.com/gpu` affiche `2` sur node-1. - Retour en arrière : `kubectl rollout undo ds/nvidia-device-plugin -n kube-system` vérifié. ## Conclusion Les erreurs de configuration des plugins de périphériques Kubernetes peuvent être évitées avec une approche disciplinée. Commencez toujours par inventorier les versions, l'environnement et l'état actuel. Apportez des modifications petites et réversibles avec une gestion appropriée des secrets. Vérifiez minutieusement à l'aide des commandes et des sorties attendues fournies. Lorsque des échecs surviennent, fiez-vous aux procédures de retour en arrière et aux étapes de récupération documentées. En adoptant ces pratiques, vous réduisez le risque de temps d'arrêt et assurez le bon fonctionnement de vos charges de travail accélérées par GPU. Commencez par mettre en œuvre l'inventaire des versions et le chemin de configuration sûr lors de votre prochaine mise à jour de plugin, puis élargissez à partir de là. N'oubliez pas : un flux de travail technique fiable rend les échecs visibles, protège les valeurs sensibles, limite les modifications à la ressource prévue et définit la récupération avant qu'un incident ne force la décision.