## Introduction Kubelet est l’agent de nœud Kubernetes qui s’assure que les conteneurs s’exécutent dans les pods conformément à leurs spécifications. Si son utilisation de base est simple, les concepts avancés comme la gestion de la configuration, le traitement des ressources et le dépannage exigent une compréhension plus fine pour fonctionner de manière fiable à grande échelle. Cet article explique les rouages, l’architecture et la configuration de Kubelet avec des exemples pratiques, en mettant l’accent sur les commandes actionnables, les sorties attendues et les stratégies de récupération. Nous ciblons les développeurs, les consultants DevOps et les équipes techniques de startups qui doivent diagnostiquer les problèmes de nœuds, optimiser l’utilisation des ressources ou sécuriser la configuration de Kubelet. Chaque exemple inclut des commandes adaptées à la version, les prérequis et les étapes de validation. Vous apprendrez à observer avant de modifier, à limiter le rayon d’impact et à documenter les chemins de récupération, des pratiques essentielles dans les environnements Kubernetes de production. ## Inventaire des versions et de l’environnement Avant toute tâche avancée sur Kubelet, établissez une base de référence claire. Cela signifie connaître la version de Kubelet, son mode de déploiement et les fichiers de configuration utilisés. Un tel inventaire permet d’éviter des modifications inappropriées et facilite la récupération. ### Identifier la version et le déploiement de Kubelet Exécutez la commande en lecture seule suivante sur le nœud pour obtenir la version de Kubelet : ```bash kubelet --version ``` Sortie attendue : ``` Kubernetes v1.28.2 ``` La méthode de déploiement est importante. Vérifiez si Kubelet s’exécute comme un service systemd (courant dans les clusters kubeadm) ou comme un binaire statique géré par un autre processus. Sur un nœud basé sur systemd, utilisez : ```bash systemctl status kubelet ``` Observez la ligne `Loaded:` ; elle indique le chemin du fichier d’unité, par exemple `/etc/systemd/system/kubelet.service`. Si Kubelet est conteneurisé (par exemple, dans certaines distributions gérées), vous devrez peut-être utiliser `docker ps` ou `crictl ps` pour le localiser. ### Inventorier les fichiers de configuration Kubelet lit la configuration à partir de plusieurs sources, avec un ordre de priorité. Les emplacements courants incluent : - Les paramètres passés au binaire kubelet (priorité la plus élevée pour de nombreuses options) - Le fichier `--config`, généralement `/var/lib/kubelet/config.yaml` - Les fichiers drop-in dans `/etc/systemd/system/kubelet.service.d/` ou `/etc/default/kubelet` - Les valeurs par défaut Pour voir la configuration active, exécutez : ```bash kubelet --config /var/lib/kubelet/config.yaml --dump-config ``` Cela affiche la configuration effective au format JSON/YAML. Comparez-la avec le fichier pour identifier les surcharges provenant des paramètres. ### Capturer l’état actuel Prenez un instantané de l’état du nœud et des métriques Kubelet pertinentes avant toute modification. Utilisez : ```bash kubectl describe node ``` Remplacez `` par le nom réel du nœud. Notez les conditions telles que `MemoryPressure`, `DiskPressure` et `PIDPressure`. Enregistrez également les horodatages pour la corrélation. Pour les métriques Kubelet en direct, si le point de terminaison des métriques Kubelet est activé (par défaut sur le port 10250), vous pouvez l’interroger avec une authentification appropriée, mais pour simplifier, de nombreux clusters exposent les métriques via l’exportateur de nœuds Prometheus. Vérifiez si le port 10255 (lecture seule) est disponible : ```bash curl -s http://localhost:10255/metrics | head ``` Remarque : le port en lecture seule est désactivé par défaut dans les versions récentes de Kubernetes pour des raisons de sécurité. Préférez utiliser `kubectl proxy` et `curl` depuis un plan de contrôle avec les autorisations appropriées. Stockez ces sorties dans un emplacement sécurisé. N’incluez jamais de secrets ni de clés privées dans votre documentation. ### Définir les signaux attendus et d’échec Pour tout changement, définissez à quoi ressemble le succès. Par exemple, si vous prévoyez d’ajuster les seuils `evictionHard`, le résultat attendu pourrait être : « La condition de nœud `MemoryPressure` reste `False` sous un stress mémoire allant jusqu’à 80 % d’utilisation. » Un signal d’échec pourrait être : « Les journaux de Kubelet montrent `Failed to admit pod` ou des avertissements `EvictionThresholdMet`. » Documentez ces éléments avant d’intervenir. ## Chemin de configuration sûr Modifier la configuration de Kubelet peut déstabiliser un nœud. Suivez un processus structuré pour minimiser les risques. ### Prérequis pour les modifications de configuration - Accès au nœud avec les privilèges sudo. - Capacité de redémarrer le service Kubelet (peut causer une brève interruption des pods ; prévoyez une fenêtre de maintenance). - Une sauvegarde du fichier de configuration actuel. - Compréhension du rôle du nœud : plan de contrôle ou worker. ### Exemple : ajuster les seuils d’éviction des pods Kubelet évince les pods lorsque les ressources du nœud sont épuisées. Les valeurs par défaut peuvent être trop agressives pour certaines charges de travail. Ajustons le seuil d’éviction stricte pour la mémoire. **Étape 1 : Observer les réglages actuels.** ```bash grep -A5 evictionHard /var/lib/kubelet/config.yaml ``` La sortie peut montrer : ```yaml evictionHard: memory.available: "100Mi" nodefs.available: "10%" imagefs.available: "15%" ``` **Étape 2 : Déterminer la valeur souhaitée.** Pour un nœud avec 32 Gio de RAM exécutant des applications sensibles à la mémoire, vous pourriez augmenter `memory.available` à `500Mi` pour réserver plus de marge. Cela réduit le risque de terminaisons OOM au prix d’une mémoire allouable plus faible. **Étape 3 : Effectuer une modification ciblée.** Modifiez le fichier de configuration à l’aide d’un éditeur de texte : ```bash sudo vi /var/lib/kubelet/config.yaml ``` Modifiez uniquement la ligne concernant la mémoire : ```yaml evictionHard: memory.available: "500Mi" ``` Enregistrez et quittez. **Étape 4 : Valider la syntaxe de la configuration.** Kubelet peut valider sa configuration sans démarrer : ```bash kubelet --config /var/lib/kubelet/config.yaml --validate ``` Aucune sortie ne signifie que la syntaxe est valide. En cas d’erreurs, corrigez-les. **Étape 5 : Redémarrer Kubelet.** ```bash sudo systemctl restart kubelet ``` **Étape 6 : Vérifier que le changement a pris effet.** Vérifiez la configuration effective de Kubelet : ```bash kubelet --config /var/lib/kubelet/config.yaml --dump-config | grep memory.available ``` La sortie attendue inclut `"memory.available": "500Mi"`. Surveillez également les conditions du nœud : ```bash kubectl get node -o jsonpath='{range .status.conditions[*]}{.type}={.status}{"\n"}{end}' ``` Recherchez la condition `MemoryPressure` avec le statut `False` et des événements indiquant aucune nouvelle éviction. ### Chemin de récupération Si les pods commencent à être évincés de manière inattendue ou si le nœud devient instable, revenez à la sauvegarde : ```bash sudo cp /var/lib/kubelet/config.yaml.bak /var/lib/kubelet/config.yaml sudo systemctl restart kubelet ``` Vérifiez avec `--dump-config` et l’état du nœud. C’est pourquoi les sauvegardes sont essentielles. ### Considérations sur le rayon d’impact Une modification sur un seul nœud n’affecte que les pods de ce nœud, sauf s’il s’agit d’un modèle de configuration partagé (par exemple, dans les scripts d’approvisionnement du cluster). Si vous utilisez un système de gestion de configuration (Ansible, Terraform), modifiez la source de vérité et déployez progressivement avec un cordon/drain du nœud pour éviter des perturbations massives des pods. ## Vérification et diagnostics Après tout changement, la vérification est essentielle. Au-delà de l’exemple ci-dessus, voici des diagnostics avancés pour Kubelet. ### Inspecter les journaux de Kubelet Comme Kubelet s’exécute en tant que service, utilisez journalctl : ```bash sudo journalctl -u kubelet -n 100 --no-pager ``` Pour suivre en direct : ```bash sudo journalctl -u kubelet -f ``` Recherchez des motifs : lignes `E` (erreur) répétées, avertissements concernant des échecs de synchronisation, etc. Corrélez avec les événements du nœud : ```bash kubectl get events --field-selector involvedObject.kind=Node ``` Si les journaux sont trop bruyants, augmentez temporairement la verbosité de Kubelet en modifiant l’unité systemd : ```bash sudo systemctl edit kubelet ``` Ajoutez : ```ini [Service] Environment="KUBELET_EXTRA_ARGS=--v=4" ``` Puis redémarrez et observez. N’oubliez pas de supprimer ceci après le débogage ; une verbosité élevée nuit aux performances. ### Interroger l’API Kubelet pour les spécifications des pods Kubelet expose une API en lecture seule (si activée) pour voir ce qu’il pense exécuter. Le point de terminaison `pods` peut être utile. Depuis le nœud : ```bash curl -s http://localhost:10255/pods ``` Cependant, le port en lecture seule (10255) est obsolète et souvent désactivé. Le port sécurisé (10250) nécessite des certificats clients. Vous pouvez utiliser `kubectl proxy` et `curl` depuis un plan de contrôle ou une machine locale : ```bash # Démarrez le proxy dans un terminal séparé kubectl proxy --port=8001 # Puis interrogez le point de terminaison des pods curl -X GET http://127.0.0.1:8001/api/v1/nodes//proxy/pods | jq . ``` Cela renvoie la liste des pods connus de Kubelet. Comparez avec `kubectl get pods --all-namespaces` pour repérer les divergences (par exemple, des conteneurs orphelins). ### Vérification des pods statiques Si vous utilisez des pods statiques (par exemple, pour les composants du plan de contrôle), vérifiez le répertoire des manifestes de pods statiques (par défaut `/etc/kubernetes/manifests`). Kubelet surveille ce répertoire et crée des pods. Pour vérifier qu’un pod statique est reconnu, recherchez dans les journaux de Kubelet des lignes telles que : ``` "Starting pod" pod="kube-system/kube-apiserver-" ``` Ou interrogez le point de terminaison `spec` de l’API Kubelet pour les pods statiques. ### Analyse approfondie des métriques Kubelet expose des métriques via le port sécurisé, généralement collectées par Prometheus. Accédez-y via `kubectl proxy` : ```bash # Démarrez le proxy s’il n’est pas déjà en cours d’exécution kubectl proxy --port=8001 # Interrogez les métriques curl -sSL http://127.0.0.1:8001/api/v1/nodes//proxy/metrics | grep kubelet_runtime_operations ``` Métriques clés : - `kubelet_runtime_operations_total` : nombre d’opérations d’exécution de conteneurs par type. - `kubelet_runtime_operations_errors_total` : erreurs dans les opérations d’exécution. - `kubelet_pod_start_duration_seconds` : temps de démarrage des pods. Des taux d’erreur élevés ou des durées longues peuvent indiquer des problèmes d’exécution. Utilisez-les pour les alertes. ## Modes de défaillance et récupération Kubelet peut échouer de diverses manières. Comprendre les modes de défaillance courants accélère la récupération. ### Nœud non prêt **Symptôme :** `kubectl get nodes` affiche `NotReady` pour le nœud. **Diagnostic :** ```bash kubectl get node -o jsonpath='{range .status.conditions[*]}{.type}={.status}{"\n"}{end}' ``` Regardez la condition `Ready` : `False` avec une raison comme `KubeletNotReady` ou `ContainerRuntimeUnhealthy`. Vérifiez les journaux de Kubelet pour les erreurs. Vérifiez également si le runtime de conteneurs fonctionne : ```bash sudo systemctl status containerd # ou docker ``` Si le runtime est arrêté, redémarrez-le : ```bash sudo systemctl restart containerd sudo systemctl restart kubelet ``` **Récupération :** Après le redémarrage, attendez 1 à 2 minutes et vérifiez l’état du nœud. S’il est toujours `NotReady`, inspectez les journaux pour des problèmes de certificat ou de réseau (par exemple, impossibilité de contacter le serveur API). ### Échec de rotation des certificats Kubelet Kubelet utilise des certificats clients pour s’authentifier auprès du serveur API. Ces certificats sont renouvelés automatiquement, mais une défaillance peut entraîner des problèmes d’accès à l’API. **Symptôme :** Les journaux de Kubelet affichent `Failed to rotate client certificate` ou `Unauthorized`. **Diagnostic :** Vérifiez l’expiration du certificat : ```bash sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates ``` S’il est expiré et non renouvelé, vérifiez le paramètre `--rotate-certificates` et l’approbateur `kubelet-serving-cert-approver` (le cas échéant). **Récupération :** Approuvez manuellement les CSR en attente : ```bash kubectl get csr | grep Pending kubectl certificate approve ``` S’il n’y a pas de CSR, redémarrez Kubelet pour déclencher une nouvelle demande. Pour prévenir ce problème, assurez-vous que le gestionnaire de contrôleurs dispose des paramètres `--cluster-signing-cert-file` et `--cluster-signing-key-file`. ### Pression disque et évictions Lorsque l’espace disque du nœud est faible, Kubelet peut évincer des pods. Si la configuration est incorrecte, cela peut entraîner un effet de battement. **Symptôme :** Évictions fréquentes de pods avec la condition `DiskPressure` à `True`. **Diagnostic :** Vérifiez l’utilisation du disque et les seuils d’éviction de Kubelet. ```bash df -h /var/lib/kubelet ``` Examinez la configuration `evictionHard` et `evictionSoft`. **Récupération :** Libérez temporairement de l’espace (supprimez les images inutilisées, les journaux) et ajustez les seuils. Pour supprimer les images inutilisées, utilisez `crictl rmi --prune` si vous utilisez containerd. Modifiez ensuite les seuils comme dans la section précédente. ## Pièges courants et comment les éviter 1. **Mauvaise compréhension de la priorité de configuration** *Pourquoi cela arrive :* Les paramètres de Kubelet remplacent les réglages du fichier de configuration, et les utilisateurs peuvent définir une valeur aux deux endroits sans le savoir. *Comment l’éviter :* Utilisez toujours `--dump-config` pour voir la configuration effective. Documentez tous les changements de paramètres et de fichiers dans votre automatisation. 2. **Ignorer les conditions du nœud** *Pourquoi cela arrive :* Les opérateurs se concentrent sur l’état des pods mais négligent les pressions au niveau du nœud. *Comment l’éviter :* Configurez des alertes de surveillance pour `MemoryPressure`, `DiskPressure` et `PIDPressure`. Utilisez régulièrement `kubectl describe node`. 3. **Seuils d’éviction trop agressifs** *Pourquoi cela arrive :* Réglage pour une utilisation maximale des ressources sans tenir compte des pics de charge. *Comment l’éviter :* Définissez des seuils conservateurs (par exemple, `memory.available: 500Mi` pour les nœuds à mémoire élevée), testez avec une charge et surveillez les événements d’éviction. 4. **Redémarrer Kubelet sans drainer** *Pourquoi cela arrive :* Oublier que le redémarrage interrompt tous les pods du nœud, provoquant une indisponibilité temporaire. *Comment l’éviter :* Utilisez `kubectl drain --ignore-daemonsets` avant les redémarrages planifiés, puis `kubectl uncordon` après. Pour les redémarrages non planifiés, assurez-vous que les pods sont résilients et disposent de budgets de perturbation appropriés. 5. **Laisser les réglages de débogage activés** *Pourquoi cela arrive :* Augmenter la verbosité ou activer des ports non sécurisés pour le débogage et oublier de revenir en arrière. *Comment l’éviter :* Documentez toute modification temporaire de configuration avec une date d’échéance, utilisez la gestion de configuration pour garantir le retour en arrière et auditez périodiquement les réglages des nœuds. 6. **Ne pas sauvegarder la configuration avant les modifications** *Pourquoi cela arrive :* Excès de confiance ou absence de processus. *Comment l’éviter :* Créez toujours une sauvegarde horodatée : `sudo cp /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.$(date +%Y%m%d)`. Testez la procédure de récupération dans un environnement hors production. ## Liste de contrôle opérationnelle Une liste de contrôle concise pour les opérations Kubelet, avec un responsable désigné et une fréquence de révision. | Tâche | Commande / Action | Résultat attendu | Responsable | Fréquence de révision | |------|------------------|-----------------|-------|------------------| | Vérifier la version de Kubelet | `kubelet --version` | La version correspond à la base du cluster (par ex., v1.28.2) | Priya Shah, Responsable Ingénierie | Mensuelle | | Vérifier les conditions du nœud | `kubectl describe node ` | Toutes les conditions sont `False` sauf `Ready=True` | Marcus Chen, Ingénieur DevOps | Hebdomadaire | | Inspecter les journaux de Kubelet | `sudo journalctl -u kubelet -n 100` | Aucune erreur répétée ; aucun message `Failed to` | Elena Rodriguez, SRE | Quotidienne (automatisée) | | Examiner la configuration effective | `kubelet --config /var/lib/kubelet/config.yaml --dump-config` | La configuration correspond à l’état souhaité ; aucune surcharge inattendue | Priya Shah, Responsable Ingénierie | Mensuelle | | Tester les seuils d’éviction | Simuler un stress mémoire sur un nœud de test | Les évictions se produisent uniquement aux seuils prévus ; les pods récupèrent | Marcus Chen, Ingénieur DevOps | Trimestrielle | | Sauvegarder la configuration | `sudo cp /var/lib/kubelet/config.yaml /var/lib/kubelet/config.yaml.bak` | Le fichier de sauvegarde existe et est lisible | Elena Rodriguez, SRE | Avant tout changement | | Surveiller l’expiration des certificats | `sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates` | Certificat valide pour >30 jours | Priya Shah, Responsable Ingénierie | Mensuelle | Chaque élément a un seul responsable, et non un groupe, pour garantir la responsabilisation. Les révisions ont lieu selon un calendrier ou dans le cadre de la gestion des changements. ## Conclusion Les concepts avancés de Kubelet, à savoir la gestion de la configuration, les diagnostics et la récupération après défaillance, exigent une discipline opérationnelle rigoureuse. En suivant les pratiques décrites ici, vous pouvez réduire les temps d’arrêt, améliorer la stabilité des nœuds et résoudre efficacement les problèmes. Commencez toujours par l’observation, effectuez des modifications ciblées avec des sauvegardes vérifiées et documentez les chemins de récupération. La liste de contrôle opérationnelle fournit une base pour la responsabilisation de l’équipe et l’amélioration continue. Pour les prochaines étapes, choisissez une vérification à faible risque de cet article, comme la vérification de la configuration effective de Kubelet avec `--dump-config`, et intégrez-la à votre routine. Mettez en place des alertes de surveillance pour les conditions du nœud et l’expiration des certificats. À mesure que vous gagnez en confiance, étendez le réglage des seuils d’éviction et l’optimisation de l’allocation des ressources. N’oubliez pas qu’un flux de travail fiable rend les défaillances visibles, protège les valeurs sensibles et limite les modifications à la ressource prévue.