## Introduction Les demandes et limites de ressources Kubernetes sont essentielles à la stabilité du cluster, mais une mauvaise configuration peut entraîner des problèmes de réseau insaisissables. Un pod privé de CPU peut connaître des résolutions DNS lentes, tandis qu'un conteneur plafonné en mémoire peut perdre des connexions ou ne pas en établir de nouvelles. Ce guide fournit une approche pratique, axée sur les commandes, pour diagnostiquer et résoudre les problèmes de réseau causés par des demandes et limites de ressources inappropriées. Nous aborderons la résolution DNS, l'allocation de ports, le routage, les vérifications de pare-feu, les tests de connectivité et les commandes de diagnostic sûres, le tout illustré par des exemples concrets. L'article suit un flux de travail systématique : d'abord, inventorier votre environnement et ses versions ; puis, ajuster en toute sécurité les configurations de ressources ; vérifier avec des commandes de diagnostic ; comprendre les modes de défaillance courants ; et adopter une liste de contrôle opérationnelle pour une gestion continue. À la fin, vous serez équipé pour identifier et résoudre les problèmes de réseau découlant de l'étranglement CPU, des limites mémoire ou d'une mauvaise allocation des ressources dans votre cluster Kubernetes. ## Inventaire de l'environnement et des versions Avant d'apporter toute modification, documentez votre environnement Kubernetes. Cela aide à reproduire les problèmes et garantit la compatibilité. Utilisez les commandes suivantes pour recueillir les informations essentielles. ### Vérifier la version de Kubernetes Exécutez : kubectl version --short Exemple de sortie attendue : Client Version: v1.24.0 Server Version: v1.24.0 Connaître à la fois les versions client et serveur est crucial car les fonctionnalités de gestion des ressources évoluent entre les versions. ### Identifier le plugin CNI et sa version Le plugin Container Network Interface (CNI) gère le réseau des pods. Pour savoir quel CNI est installé et sa version, inspectez les images des pods concernés. Pour Calico : kubectl get pods -n kube-system -l k8s-app=calico-node -o jsonpath='{.items[0].spec.containers[0].image}' Exemple de sortie : calico/node:v3.22.0 Pour d'autres plugins CNI (Flannel, Weave, Cilium), ajustez le sélecteur d'étiquettes en conséquence. Étiquettes courantes : - Flannel : app=flannel - Weave : name=weave-net - Cilium : k8s-app=cilium ### Lister les nœuds et la capacité en ressources Vérifiez la capacité des nœuds pour comprendre la disponibilité des ressources : kubectl get nodes -o custom-columns='NAME:.metadata.name,CPU:.status.capacity.cpu,MEMORY:.status.capacity.memory' Exemple de sortie : NAME CPU MEMORY node-1 4 16Gi node-2 8 32Gi Cela montre le total des ressources allouables par nœud, ce qui importe lorsque les pods sont expulsés en raison de la pression sur les ressources. ### Lister tous les pods avec leurs demandes et limites de ressources Pour voir les configurations de ressources actuelles de tous les pods : kubectl get pods --all-namespaces -o custom-columns='NAMESPACE:.metadata.namespace,POD:.metadata.name,CPU_REQ:.spec.containers[*].resources.requests.cpu,CPU_LIM:.spec.containers[*].resources.limits.cpu,MEM_REQ:.spec.containers[*].resources.requests.memory,MEM_LIM:.spec.containers[*].resources.limits.memory' Cela produit un tableau large. Pour plus de lisibilité, filtrez avec awk ou utilisez un outil comme kubectl-neat . Exemple de sortie filtrée : NAMESPACE POD CPU_REQ CPU_LIM MEM_REQ MEM_LIM kube-system coredns-64897985 100m - 70Mi 170Mi kube-system kube-proxy-abcde - - - - default myapp-7c9d8b 200m 500m 128Mi 256Mi Notez que certains pods n'ont ni demandes ni limites ; ils sont sans restriction et peuvent consommer des ressources illimitées, au détriment des autres. ### Documenter les politiques réseau et les quotas de ressources Les politiques réseau peuvent bloquer le trafic même lorsque les ressources sont adéquates. Listez-les : kubectl get networkpolicies --all-namespaces Vérifiez les quotas de ressources qui peuvent limiter l'utilisation totale dans un espace de noms : kubectl get resourcequota --all-namespaces Si un quota est défini, il peut empêcher la planification des pods ou provoquer des expulsions, affectant indirectement le réseau. Prérequis pour ce guide : - kubectl configuré avec accès au cluster et autorisations appropriées. - Compréhension de base des ressources Kubernetes (pods, déploiements, services). - Permission de visualiser et modifier les spécifications des pods (ou capacité de supprimer/recréer des pods). Cet inventaire constitue la base pour corréler les contraintes de ressources avec le comportement du réseau.
Question rapide 1 sur 2 Que se passe-t-il lorsqu'un Pod node-local-dns tente d'utiliser plus de mémoire que disponible ? - Le conteneur est redémarré automatiquement sans interruption de service. - Le système d'exploitation peut arrêter le conteneur, provoquant une brève interruption DNS. - Le kubelet réduit dynamiquement la limite de mémoire du conteneur. - Les requêtes DNS sont routées vers le service DNS du cluster.
Si un Pod node-local-dns tente d'utiliser plus de mémoire que disponible, le système d'exploitation peut arrêter le conteneur. Le conteneur fait partie d'un DaemonSet, il est donc redémarré, mais il y a une brève interruption DNS car les règles de filtrage de paquets dirigent les requêtes vers le pod défaillant.
## Chemin de configuration sûr Lorsque vous ajustez les demandes et limites de ressources pour résoudre des problèmes de réseau, procédez avec prudence pour éviter toute interruption de service. Une approche par étapes minimise les risques. ### Étape 1 : Identifier le pod ou le déploiement problématique Utilisez des étiquettes ou des noms pour réduire la portée. Par exemple, si les résolutions DNS sont lentes, le problème peut provenir des pods CoreDNS. Exécutez : kubectl get pods -n kube-system -l k8s-app=kube-dns Notez les noms des pods et leurs paramètres de ressources actuels. ### Étape 2 : Capturer la configuration actuelle Avant de modifier quoi que ce soit, sauvegardez le déploiement existant : kubectl get deployment myapp -o yaml > myapp-deployment-backup.yaml Cette sauvegarde permet un retour rapide en arrière si les modifications entraînent de nouveaux problèmes. ### Étape 3 : Utiliser une approche par étapes Pour les charges de travail critiques, testez d'abord les modifications sur un déploiement canari ou avec une étiquette temporaire. Par exemple, si un pod est étranglé au niveau CPU et provoque des résolutions DNS lentes, et qu'il n'a actuellement aucune limite CPU, définissez d'abord une limite généreuse, puis réduisez progressivement si nécessaire. Appliquez un correctif au déploiement avec un patch JSON : kubectl patch deployment myapp --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/resources", "value": {"requests": {"cpu": "100m", "memory": "128Mi"}, "limits": {"cpu": "500m", "memory": "256Mi"}}}]' Cela ajoute un bloc de ressources au premier conteneur. Si le déploiement a plusieurs conteneurs, ajustez l'index. Alternativement, appliquez un fichier YAML modifié avec kubectl apply -f myapp-resources.yaml après édition. ### Étape 4 : Surveiller le déploiement Vérifiez l'état du déploiement : kubectl rollout status deployment/myapp Sortie attendue : deployment "myapp" successfully rolled out Si le déploiement échoue, enquêtez avec kubectl describe deployment myapp et kubectl get events . ### Étape 5 : Validation à blanc (dry-run) Avant d'appliquer des modifications en production, utilisez dry-run pour valider le YAML : kubectl apply -f myapp-resources.yaml --dry-run=client Cela vérifie la syntaxe sans apporter de modifications. ### Étape 6 : Modifications directes sur les pods Pour les pods autonomes (non gérés par un contrôleur), vous ne pouvez pas mettre à jour les ressources en place. Supprimez et recréez le pod avec la spécification mise à jour. Exemple : kubectl delete pod mypod # Puis appliquez une nouvelle spécification de pod avec les ressources souhaitées. Conservez toujours des sauvegardes et utilisez le contrôle de version pour les manifestes afin de permettre un retour rapide. ## Vérification et diagnostics Après avoir ajusté les ressources, vérifiez la fonctionnalité réseau et diagnostiquez si les problèmes persistent. Utilisez ces commandes de manière systématique. ### Vérifier l'état des pods et l'utilisation des ressources Commencez par l'état des pods : kubectl get pods Ensuite, vérifiez l'utilisation réelle des ressources : kubectl top pod myapp-pod Exemple de sortie : NAME CPU(cores) MEMORY(bytes) myapp-pod 50m 100Mi Comparez l'utilisation aux limites. Si l'utilisation est proche des limites, envisagez de les augmenter. Par exemple, si la limite CPU est de 100m et l'utilisation de 90m, le pod est probablement étranglé. ### Tester la résolution DNS depuis un pod Créez un pod busybox temporaire pour le diagnostic : kubectl run -it --rm debug --image=busybox --restart=Never -- sh Dans le pod, exécutez : nslookup kubernetes.default Sortie attendue : Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: kubernetes.default Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local Si le DNS échoue ou expire, vérifiez le CPU et la mémoire des pods CoreDNS. Ils peuvent être expulsés ou étranglés. Utilisez kubectl top pods -n kube-system pour voir leur utilisation. ### Tester la connectivité vers un service Depuis le même pod busybox, testez la connectivité HTTP : wget -qO- http://myservice.default.svc.cluster.local:8080 Attendu : réponse du service. Si aucune réponse, vérifiez les endpoints du service : kubectl get endpoints myservice Si les endpoints sont vides, le sélecteur du service peut ne correspondre à aucun pod sain. ### Vérifier les politiques réseau Les politiques réseau peuvent bloquer le trafic même si les ressources sont correctes. Listez les politiques dans l'espace de noms : kubectl get networkpolicies -n default Décrivez une politique spécifique pour voir ses règles : kubectl describe networkpolicy allow-web -n default Recherchez des règles d'entrée/sortie trop restrictives. ### Inspecter les journaux des pods pour les erreurs réseau Vérifiez les journaux récents : kubectl logs myapp-pod --tail=50 Recherchez des erreurs de connexion refusée, de délai d'attente ou de résolution DNS. ### Utiliser le transfert de port pour les tests locaux Pour tester la connectivité depuis votre machine locale : kubectl port-forward pod/myapp-pod 8080:80 Ouvrez ensuite http://localhost:8080 dans un navigateur ou utilisez curl . Cela contourne le routage du service et aide à isoler les problèmes. ### Détecter l'étranglement CPU L'étranglement CPU peut être déduit de kubectl top si l'utilisation atteint constamment la limite. Pour plus de détails, si vous avez accès au nœud, inspectez les statistiques cgroup : cat /sys/fs/cgroup/cpu/cpu.stat Recherchez nr_throttled et throttled_time . Des valeurs élevées indiquent un étranglement. ### Vérifier les journaux de kube-proxy pour les problèmes de routage Les problèmes de routage peuvent être dus à kube-proxy. Inspectez ses journaux : kubectl logs -n kube-system kube-proxy-xxxxx Remplacez par le nom réel du pod. Recherchez des erreurs liées à iptables ou IPVS. ### Vérifier les OOM kills et les expulsions Si les pods sont fréquemment expulsés en raison des limites mémoire, vérifiez les événements : kubectl describe pod myapp-pod | grep -A5 Events Recherchez les messages OOMKilled ou Evicted . Les OOM kills peuvent provoquer des réinitialisations de connexion et des échecs de requêtes. Ces diagnostics aident à identifier si les contraintes de ressources sont à l'origine des pannes réseau.
Question rapide 2 sur 2 Quel est le compromis lié à la définition de limites CPU comme mentionné dans la référence ? - Les limites CPU empêchent les problèmes de voisin bruyant mais peuvent provoquer une limitation même avec une capacité CPU disponible. - Les limites CPU améliorent toujours les performances des charges de travail sensibles à la latence. - Les limites CPU ne sont utiles que dans les environnements mono-tenant. - Les limites CPU n'ont aucun impact sur la limitation CPU.
Définir des limites CPU empêche les problèmes de voisin bruyant dans les environnements multi-tenant, mais elles peuvent provoquer une limitation même lorsque le nœud dispose d'une capacité CPU disponible, ce qui peut dégrader les performances des charges de travail sensibles à la latence.
## Modes de défaillance courants et récupération Comprendre les schémas de défaillance typiques accélère le dépannage. Voici des scénarios courants avec symptômes et étapes de récupération. ### Étranglement CPU entraînant des résolutions DNS lentes Symptôme : Échecs intermittents de résolution DNS ou latence élevée. Les applications signalent des délais d'attente lors de la connexion aux services. Cause : Les pods CoreDNS peuvent être étranglés au niveau CPU sous charge, surtout si les limites sont trop basses. Récupération : Augmentez la limite CPU pour CoreDNS. Modifiez le déploiement : kubectl edit deployment coredns -n kube-system Changez les ressources du conteneur, par exemple de : resources: limits: cpu: 200m memory: 170Mi requests: cpu: 100m memory: 70Mi à : resources: limits: cpu: 500m memory: 300Mi requests: cpu: 200m memory: 150Mi Enregistrez et quittez. Surveillez l'utilisation CPU de CoreDNS avec kubectl top pods -n kube-system . ### Limite mémoire provoquant des OOM kills Symptôme : Le pod redémarre fréquemment, connexions interrompues, interruption de service. kubectl get pods montre un compteur de redémarrages en augmentation. Cause : La limite mémoire du conteneur est trop basse pour sa charge de travail, entraînant des arrêts pour mémoire insuffisante (OOM kills) par le noyau. Récupération : Augmentez la limite mémoire ou corrigez une fuite de mémoire dans l'application. Vérifiez le dernier état du pod : kubectl describe pod myapp-pod | grep -A10 'Last State' Si cela indique OOMKilled , augmentez la limite mémoire dans la spécification du déploiement. ### Expulsion de pod due à la pression sur le nœud Symptôme : Les pods sont expulsés des nœuds, les endpoints réseau disparaissent, les services deviennent injoignables. Cause : Le nœud est sous pression mémoire ou disque, et Kubernetes expulse les pods pour récupérer des ressources. Récupération : Ajustez les demandes de ressources pour correspondre à l'utilisation réelle afin d'améliorer la planification, ou ajoutez de la capacité au nœud. Vérifiez les conditions du nœud : kubectl describe node node-1 | grep -A5 Conditions Si MemoryPressure ou DiskPressure est True , enquêtez et résolvez. ### Mauvaise configuration de la politique réseau Symptôme : Trafic bloqué entre les pods même lorsque les ressources sont correctes. Les connexions expirent ou sont refusées. Cause : Les politiques réseau peuvent être trop restrictives. Récupération : Examinez et modifiez les politiques réseau. Utilisez kubectl describe networkpolicy pour voir les règles, et ajustez les sélecteurs et les règles d'entrée/sortie. ### Échec de résolution DNS dû à l'épuisement des ressources CoreDNS Symptôme : Les requêtes DNS expirent systématiquement. nslookup depuis un pod se bloque. Cause : Les pods CoreDNS peuvent avoir des ressources insuffisantes ou avoir été expulsés, ne laissant aucun service DNS. Récupération : Vérifiez l'état des pods CoreDNS : kubectl get pods -n kube-system -l k8s-app=kube-dns Si les pods sont absents ou en boucle de crash, augmentez l'échelle ou ajustez les ressources. Envisagez d'utiliser l'autoscaler horizontal de pods (HPA) pour CoreDNS : kubectl autoscale deployment coredns -n kube-system --cpu-percent=80 --min=2 --max=5 ### Procédures de retour en arrière (rollback) Si les modifications de ressources causent des problèmes, revenez rapidement à la configuration précédente. - Pour les déploiements : kubectl rollout undo deployment/myapp - Pour les pods créés manuellement : supprimez et recréez avec la spécification d'origine de la sauvegarde. - Pour CoreDNS : kubectl rollout undo deployment coredns -n kube-system Après le retour en arrière, vérifiez que le réseau est rétabli avec les tests de la section précédente. Continuez à surveiller les problèmes récurrents. ## Liste de contrôle opérationnelle Prévenez les problèmes de réseau causés par une mauvaise configuration des ressources avec cette liste de contrôle continue. ### Surveillance et alertes - Exécutez kubectl top pods --all-namespaces régulièrement, au moins quotidiennement. - Configurez des alertes pour les pods approchant leurs limites (par exemple, >80 % de CPU ou de mémoire pendant des périodes prolongées). Utilisez Prometheus et Alertmanager si disponibles. - Surveillez l'utilisation des ressources des nœuds : kubectl top nodes . ### Réviser périodiquement les paramètres de ressources - Révisez les demandes et limites de ressources chaque trimestre ou après des changements d'application significatifs. - Comparez l'utilisation réelle ( kubectl top ) avec les demandes/limites configurées ; ajustez pour éviter le sur- ou sous-provisionnement. ### Fiabilité du DNS - Assurez-vous que CoreDNS a au moins 2 répliques pour la haute disponibilité. Augmentez l'échelle avec la taille du cluster : kubectl scale deployment coredns -n kube-system --replicas=3 pour les grands clusters. - Testez la résolution DNS après toute mise à niveau ou modification du cluster : kubectl run -it --rm dns-test --image=busybox --restart=Never -- nslookup kubernetes.default ### Validation des politiques réseau - Maintenez une matrice de tests de connectivité. Pour chaque communication service-à-service, exécutez des tests périodiques depuis un pod de débogage. - Après modification des politiques réseau, exécutez la matrice de tests pour vous assurer qu'il n'y a pas de blocages involontaires. ### Contrôle de version et documentation - Conservez tous les manifestes dans un contrôle de version (Git). Révisez les changements avant fusion. - Documentez les valeurs de ressources standard pour les types d'application courants. Par exemple : Type d'application Demande CPU Limite CPU Demande mémoire Limite mémoire Frontend web 100m 500m 128Mi 256Mi Backend API 250m 1 256Mi 512Mi Base de données 500m 2 1Gi 2Gi ### Appliquer des valeurs par défaut avec LimitRange et ResourceQuota Utilisez LimitRange pour appliquer des demandes et limites par défaut aux conteneurs qui ne les spécifient pas. Exemple : apiVersion: v1 kind: LimitRange metadata: name: default-limits namespace: default spec: limits: - default: cpu: 500m memory: 256Mi defaultRequest: cpu: 100m memory: 128Mi type: Container Appliquez avec : kubectl apply -f limitrange.yaml Utilisez ResourceQuota pour limiter l'utilisation totale des ressources dans un espace de noms et prévenir le sur-engagement : apiVersion: v1 kind: ResourceQuota metadata: name: namespace-quota namespace: default spec: hard: requests.cpu: "4" requests.memory: "8Gi" limits.cpu: "8" limits.memory: "16Gi" Appliquez avec kubectl apply -f resourcequota.yaml . ### Formation de l'équipe et communication - Formez les développeurs à définir des demandes/limites appropriées. Insistez sur l'impact sur le réseau. - Partagez ce guide de dépannage avec l'équipe des opérations. Utilisez cette liste de contrôle pour gérer proactivement les ressources et prévenir les problèmes de réseau. ## Conclusion Les demandes et limites de ressources Kubernetes ont un impact direct sur les performances et la fiabilité du réseau. L'étranglement CPU peut ralentir les résolutions DNS, les limites mémoire peuvent provoquer des OOM kills et des connexions interrompues, et les expulsions de pods peuvent perturber les endpoints de service. En suivant une approche systématique—commençant par un inventaire complet de l'environnement, apportant des modifications de configuration en toute sécurité, vérifiant avec des commandes de diagnostic concrètes et préparant des procédures de retour en arrière—vous pouvez diagnostiquer et résoudre efficacement ces problèmes. Adoptez la liste de contrôle opérationnelle pour maintenir un environnement réseau sain. Une surveillance régulière, des révisions périodiques des ressources et des valeurs par défaut appropriées avec LimitRange et ResourceQuota aident à prévenir les problèmes avant qu'ils n'affectent vos applications. Avec ces pratiques, votre cluster Kubernetes offrira un réseau fiable et efficace.