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.
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.
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-namespacesré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=3pour 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.