Introduction
Le réseau Kubernetes est souvent l'aspect le plus difficile de l'exploitation des clusters. Lorsque les pods ne peuvent pas communiquer entre eux, que les services ne répartissent pas correctement la charge ou que les requêtes DNS expirent, les développeurs et les opérateurs ont besoin d'une approche systématique pour diagnostiquer et résoudre rapidement les problèmes. Ce guide fournit des techniques de dépannage pratiques et axées sur les commandes, fondées sur des scénarios réels. Nous couvrirons la résolution DNS, la connectivité des services et des pods, le comportement de kube-proxy et du CNI, ainsi que des méthodes de diagnostic sûres. En suivant les exemples, vous pourrez réduire les temps d'arrêt et gagner en confiance dans votre pile réseau Kubernetes.
Les problèmes de réseau peuvent se manifester de manière subtile : un service qui renvoie par intermittence des erreurs 503, des pods bloqués en état ContainerCreating ou des requêtes DNS qui expirent sporadiquement. Une méthodologie structurée évite de tâtonner et réduit le temps moyen de résolution. Ce guide met l'accent sur des commandes pratiques, des sorties attendues et des étapes concrètes de récupération.
Avant de vous plonger dans des symptômes spécifiques, établissez une compréhension de base des composants réseau de votre cluster. Cela inclut le plugin Container Network Interface (CNI), le mode de kube-proxy, le module DNS et la topologie réseau sous-jacente des nœuds. Chaque composant a ses propres modes de défaillance et surfaces de diagnostic.
Inventaire des versions et de l'environnement
Avant de dépanner, établissez un inventaire clair de votre environnement Kubernetes. Cela inclut la version du cluster, le plugin CNI, le mode de kube-proxy et le système d'exploitation des nœuds. Connaître ces détails évite les erreurs de diagnostic et aide lors de la consultation de la documentation ou des forums communautaires.
Commencez par vérifier la version du serveur Kubernetes :
kubectl version --short
Exemple de sortie attendue :
Client Version: v1.28.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.28.2
Identifiez le plugin CNI utilisé. Les CNI courants incluent Calico, Flannel, Cilium et Weave. Vous pouvez souvent le trouver en listant les pods dans l'espace de noms kube-system :
kubectl get pods -n kube-system | grep -E 'calico|flannel|cilium|weave'
Exemple de sortie :
calico-node-abcde 1/1 Running 0 5d
calico-kube-controllers-12345 1/1 Running 0 5d
Si aucun pod CNI n'est visible, vérifiez les fichiers de configuration CNI sur le nœud :
ls /etc/cni/net.d/
Les fichiers courants incluent 10-calico.conflist, 10-flannel.conflist ou 05-cilium.conf.
Vérifiez le mode de kube-proxy :
kubectl get pods -n kube-system -l k8s-app=kube-proxy -o yaml | grep -A1 'mode:'
La sortie typique inclut mode: iptables ou mode: ipvs. Vous pouvez également vérifier la ConfigMap de kube-proxy :
kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode
Si vous utilisez kubeadm, la ConfigMap de kube-proxy contient souvent :
mode: "iptables"
ou
mode: "ipvs"
Rassemblez les informations sur les nœuds :
kubectl get nodes -o wide
Cela affiche les adresses IP des nœuds, le système d'exploitation et le runtime de conteneurs. Exemple :
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
node01 Ready control-plane 10d v1.28.2 172.31.0.10 <none> Ubuntu 22.04.3 LTS 5.15.0-91-generic containerd://1.7.2
node02 Ready <none> 10d v1.28.2 172.31.0.11 <none> Ubuntu 22.04.3 LTS 5.15.0-91-generic containerd://1.7.2
Vérifiez le CIDR du réseau des pods pour vous assurer qu'il ne chevauche pas les CIDR des nœuds ou des services :
kubectl cluster-info dump | grep -m 1 cluster-cidr
ou inspectez le manifeste de kube-controller-manager sur un nœud du plan de contrôle :
sudo grep cluster-cidr /etc/kubernetes/manifests/kube-controller-manager.yaml
Exemple de sortie :
- --cluster-cidr=10.244.0.0/16
Prérequis pour un dépannage sûr :
- Accès au cluster avec kubectl configuré.
- Permission de visualiser et d'exécuter des commandes dans les espaces de noms pertinents.
- Compréhension de la topologie du cluster (par exemple, mono ou multi-nœuds, fournisseur cloud).
- Un processus de contrôle des modifications pour toute modification.
- Capacité de se connecter en SSH aux nœuds si nécessaire pour des diagnostics au niveau du nœud.
- Outils réseau comme
ping,curl,dig,tcpdumpetiptablesdisponibles ou installables.
Un pilote limité, comme recommandé pour le déploiement initial, est également utile pour le dépannage : testez les modifications sur un service ou un espace de noms avant de les déployer à l'échelle du cluster.
| Composant | Commande de vérification | Exemple de sortie |
|---|---|---|
| Version de Kubernetes | kubectl version --short | Server Version: v1.28.2 |
| Plugin CNI | kubectl get pods -n kube-system | grep calico | calico-node-abcde 1/1 Running |
| Mode de kube-proxy | kubectl get pods -n kube-system -l k8s-app=kube-proxy -o yaml | grep mode | mode: iptables |
| IP des nœuds | kubectl get nodes -o wide | node01 172.31.0.10 |
| CIDR des pods | grep cluster-cidr /etc/kubernetes/manifests/kube-controller-manager.yaml | --cluster-cidr=10.244.0.0/16 |
Chemin de configuration sûr
Lorsque vous apportez des modifications pour résoudre des problèmes de réseau, commencez toujours par des modifications étroites et réversibles. Par exemple, si vous soupçonnez un problème de configuration de kube-proxy, sauvegardez la ConfigMap actuelle avant de la modifier :
kubectl get configmap kube-proxy -n kube-system -o yaml > kube-proxy-config-backup.yaml
Modifiez ensuite avec kubectl edit configmap kube-proxy -n kube-system et redémarrez les pods kube-proxy :
kubectl rollout restart daemonset kube-proxy -n kube-system
Pour les modifications DNS, modifiez la configuration de CoreDNS seulement après sauvegarde :
kubectl get configmap coredns -n kube-system -o yaml > coredns-backup.yaml
Utilisez kubectl apply -f avec un fichier modifié plutôt que des modifications impératives pour suivre les changements. Après application, redémarrez CoreDNS :
kubectl rollout restart deployment coredns -n kube-system
Lors de l'ajustement des politiques réseau, commencez par autoriser tout le trafic dans un espace de noms de test pour confirmer que le moteur de politique fonctionne :
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
namespace: test-ns
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- {}
egress:
- {}
Appliquez cette politique avec :
kubectl apply -f allow-all.yaml -n test-ns
Testez ensuite la connectivité depuis un pod dans cet espace de noms. Si cela fonctionne, resserrez progressivement la politique. Si cela échoue, le problème peut venir du moteur de politique du CNI.
Utilisez toujours kubectl diff -f file.yaml avant d'appliquer pour voir ce qui va changer :
kubectl diff -f networkpolicy.yaml
Exemple de sortie montrant les modifications proposées :
+ ingress:
+ - from:
+ - podSelector:
+ matchLabels:
+ role: frontend
Pour les modifications du CNI, consultez la documentation du fournisseur. De nombreux CNI permettent une configuration par nœud ou par pool. Évitez les modifications à l'échelle du cluster sans test préalable. Par exemple, Calico permet de définir des configurations par nœud en utilisant des surcharges spécifiques au nœud. Créez une FelixConfiguration spécifique au nœud :
apiVersion: crd.projectcalico.org/v1
kind: FelixConfiguration
metadata:
name: node.node02
spec:
ipipEnabled: false
Appliquez-la uniquement à ce nœud et surveillez avant de la déployer sur les autres.
Vérification et diagnostics
Une vérification systématique est essentielle. Commencez par le DNS car de nombreux problèmes de connectivité proviennent d'échecs de résolution de noms.
Vérifications de la résolution DNS
Vérifiez la résolution DNS depuis un pod :
kubectl run -it --rm debug --image=busybox --restart=Never -- 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, vérifiez les pods CoreDNS :
kubectl get pods -n kube-system -l k8s-app=kube-dns
Sortie attendue :
NAME READY STATUS RESTARTS AGE
coredns-787d4945fb-2v8hx 1/1 Running 0 5d
coredns-787d4945fb-6pwqn 1/1 Running 0 5d
Consultez les journaux de CoreDNS :
kubectl logs -n kube-system -l k8s-app=kube-dns
Recherchez des erreurs comme SERVFAIL ou NXDOMAIN pour les noms internes. Si les pods ne peuvent pas atteindre l'IP du service CoreDNS, testez la connectivité vers l'IP du service (ClusterIP) :
kubectl get svc kube-dns -n kube-system
Exemple :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 10d
Depuis un pod, exécutez :
kubectl exec -it <pod-name> -- nc -zv 10.96.0.10 53
Si la connexion est refusée, kube-proxy ou CoreDNS est peut-être en panne.
Connectivité entre pods
Testez la connectivité entre pods : obtenez les IP des pods et exécutez ping ou curl.
kubectl get pods -o wide
Exemple :
NAME READY STATUS IP NODE
web-5dcb957ccc-abcde 1/1 Running 10.244.1.5 node02
api-6f49d5c5b5-xyzab 1/1 Running 10.244.2.3 node01
Depuis un pod, envoyez un ping à l'IP d'un autre pod :
kubectl exec web-5dcb957ccc-abcde -- ping -c 4 10.244.2.3
Sortie attendue en cas de succès :
PING 10.244.2.3 (10.244.2.3): 56 data bytes
64 bytes from 10.244.2.3: seq=0 ttl=62 time=0.823 ms
64 bytes from 10.244.2.3: seq=1 ttl=62 time=0.745 ms
64 bytes from 10.244.2.3: seq=2 ttl=62 time=0.711 ms
64 bytes from 10.244.2.3: seq=3 ttl=62 time=0.698 ms
--- 10.244.2.3 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
Si le ping échoue, testez la communication entre nœuds avec un protocole autre qu'ICMP, car certains clusters désactivent ICMP. Utilisez nc ou curl :
kubectl exec web-5dcb957ccc-abcde -- nc -zv 10.244.2.3 80
Attendu : Connection to 10.244.2.3 80 port [tcp/http] succeeded!
Connectivité des services
Testez la connectivité des services :
kubectl get svc
Exemple :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service ClusterIP 10.96.123.45 <none> 80/TCP 2h
Depuis un pod, faites un curl vers le service :
kubectl exec <pod-name> -- curl http://my-service
Ou si le nom du service se résout :
kubectl exec <pod-name> -- curl http://my-service.default.svc.cluster.local
Attendu : HTTP 200 et corps de réponse.
Vérifiez les endpoints du service :
kubectl get endpoints my-service
Exemple :
NAME ENDPOINTS AGE
my-service 10.244.1.5:8080 2h
Si les endpoints sont vides, le sélecteur du service ne correspond à aucun pod. Vérifiez le sélecteur :
kubectl describe svc my-service
Comparez le sélecteur avec les libellés des pods :
kubectl get pods -l app=my-app --show-labels
Vérification des règles de kube-proxy
Vérifiez les règles de kube-proxy (si mode iptables). Sur un nœud, exécutez :
sudo iptables-save | grep my-service
La sortie attendue inclut des règles DNAT :
-A KUBE-SERVICES -d 10.96.123.45/32 -p tcp -m comment --comment "default/my-service: cluster IP" -m tcp --dport 80 -j KUBE-SVC-ABCDEF123456
Inspectez ensuite la chaîne KUBE-SVC :
sudo iptables-save | grep KUBE-SVC-ABCDEF123456
Attendu :
-A KUBE-SVC-ABCDEF123456 -m comment --comment "default/my-service:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-XYZ
-A KUBE-SVC-ABCDEF123456 -m comment --comment "default/my-service:" -j KUBE-SEP-UVW
Chaque chaîne KUBE-SEP correspond à un endpoint.
Si kube-proxy est en mode IPVS, utilisez ipvsadm :
sudo ipvsadm -L -n
La sortie attendue montre les services virtuels et les serveurs réels :
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.96.123.45:80 rr
-> 10.244.1.5:8080 Masq 1 0 0
Utilisez kubectl describe pour examiner les événements et les endpoints des services et des pods :
kubectl describe pod <pod-name>
Recherchez des événements liés à des erreurs de configuration réseau.
| Vérification | Commande | Résultat attendu |
|---|---|---|
| Résolution DNS | nslookup kubernetes.default | Renvoie ClusterIP 10.96.0.1 |
| Pods CoreDNS | kubectl get pods -n kube-system -l k8s-app=kube-dns | Tous en Running |
| Ping entre pods | kubectl exec pod-a -- ping pod-b-ip | 0% de perte de paquets |
| Curl vers service | kubectl exec pod -- curl http://svc:port | HTTP 200 ou attendu |
| Endpoints | kubectl get endpoints svc | IP des pods listées |
| Règles kube-proxy | sudo iptables-save | grep svc | Règle DNAT présente |
Modes de défaillance et récupération
Les modes de défaillance réseau courants incluent une mauvaise configuration DNS, kube-proxy qui ne fonctionne pas, des erreurs du plugin CNI et des politiques réseau qui bloquent le trafic.
Défaillances DNS
Si les pods CoreDNS plantent, consultez les journaux :
kubectl logs -n kube-system -l k8s-app=kube-dns --previous
Causes courantes :
- Corefile mal configuré (par exemple, mauvais serveur amont, erreurs du plugin forward).
- Limites de ressources (CPU/mémoire) provoquant des arrêts OOM.
- Problèmes DNS du nœud affectant CoreDNS.
Étapes de récupération :
- Restaurez la ConfigMap de CoreDNS depuis la sauvegarde :
kubectl apply -f coredns-backup.yaml
- Vérifiez et ajustez les limites de ressources :
kubectl get deployment coredns -n kube-system -o yaml
Recherchez resources dans la spécification du conteneur. Augmentez si nécessaire.
- Redémarrez CoreDNS :
kubectl rollout restart deployment coredns -n kube-system
Exemple : Si vous voyez SERVFAIL pour les domaines externes, vérifiez la directive forward dans le Corefile. Un serveur amont mal configuré peut pointer vers un résolveur inexistant. Corrigez-le et redémarrez.
Défaillance de kube-proxy
Si les pods kube-proxy ne fonctionnent pas, les services peuvent ne pas recevoir les règles iptables. Vérifiez :
kubectl get pods -n kube-system -l k8s-app=kube-proxy
Si les pods sont en Pending ou CrashLoopBackOff, consultez les journaux :
kubectl logs -n kube-system -l k8s-app=kube-proxy
Erreurs courantes :
Failed to list *v1.Service: Unauthorizeden raison d'une mauvaise configuration RBAC.Failed to start IPVS managersi les modules IPVS sont manquants.
Récupération :
- Si RBAC, vérifiez le ClusterRole et le ClusterRoleBinding pour kube-proxy.
- Si IPVS, installez les modules du noyau requis sur les nœuds et définissez le mode sur ipvs.
- Si problème de configuration, restaurez la ConfigMap de kube-proxy depuis la sauvegarde et redémarrez.
Supprimez les pods pour forcer leur recréation :
kubectl delete pod -n kube-system -l k8s-app=kube-proxy
Kubernetes les recréera via le DaemonSet.
Erreurs CNI
Pods bloqués en ContainerCreating avec des erreurs CNI. Vérifiez la description du pod :
kubectl describe pod <pod-name>
Recherchez des événements comme :
Warning FailedCreatePodSandBox 2m kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "...": plugin type="calico" failed (add): unable to allocate IP address: no available IPs in pool
Cela indique une épuisement des adresses IP. Vérifiez les pools IP pour Calico :
calicoctl get ippool -o wide
Si épuisé, étendez le pool ou nettoyez les IP inutilisées.
Consultez les journaux CNI du nœud, souvent dans /var/log/calico ou via kubectl logs pour le pod CNI :
kubectl logs -n kube-system calico-node-abcde
Assurez-vous que le fichier de configuration CNI est correct et que les binaires existent :
ls /opt/cni/bin
cat /etc/cni/net.d/10-calico.conflist
Si les binaires sont manquants, réinstallez le CNI ou copiez-les depuis un nœud fonctionnel.
Politique réseau trop restrictive
Si une nouvelle politique interrompt le trafic existant, supprimez la politique pour rétablir la connectivité :
kubectl delete networkpolicy <policy-name> -n <namespace>
Exemple :
kubectl delete networkpolicy default-deny -n production
Vérifiez ensuite que le trafic circule. Si la politique était intentionnelle, modifiez-la pour autoriser le trafic nécessaire.
Stratégies de retour en arrière
- Conservez des sauvegardes de toute la configuration (ConfigMaps, fichiers YAML).
- Utilisez un système de contrôle de version pour les manifestes.
- Testez les modifications dans un espace de noms ou un cluster séparé.
- Ayez un déploiement canari pour les mises à jour critiques.
- Utilisez
kubectl rollout undopour les Deployments ou DaemonSets :
kubectl rollout undo daemonset kube-proxy -n kube-system
- Pour les modifications iptables, revenez en arrière en restaurant les règles précédentes et en redémarrant kube-proxy.
Exemple : Si une modification de règle iptables a cassé le réseau du nœud, revenez en exécutant iptables-restore avec une sauvegarde enregistrée avant la modification, puis redémarrez kube-proxy.
Liste de contrôle opérationnelle
Utilisez cette liste de contrôle pour des vérifications régulières de l'état du réseau et le dépannage :
- Vérifiez que les pods kube-proxy fonctionnent :
kubectl get pods -n kube-system -l k8s-app=kube-proxy - Vérifiez les pods CoreDNS :
kubectl get pods -n kube-system -l k8s-app=kube-dns - Testez périodiquement la résolution DNS depuis un pod de test :
kubectl run -it --rm debug --image=busybox -- nslookup kubernetes.default - Vérifiez les interfaces réseau et les routes des nœuds :
ip routeetip addrsur les nœuds. - Surveillez la santé et les journaux du plugin CNI :
kubectl logs -n kube-system -l k8s-app=calico-node --tail=50 - Passez en revue les politiques réseau pour détecter des restrictions non intentionnelles :
kubectl get networkpolicies --all-namespaces - Validez que les endpoints des services correspondent aux pods :
kubectl get endpoints --all-namespaces - Effectuez des tests de connectivité entre les pods sur différents nœuds : Utilisez ping ou nc comme montré précédemment.
- Conservez des sauvegardes de configuration et documentez les modifications.
- Utilisez
kubectl diffavant d'appliquer des modifications réseau.
Fréquence recommandée et outils :
| Élément de la liste | Fréquence | Commande/Outil |
|---|---|---|
| Vérifier kube-proxy | Quotidien | kubectl get pods -n kube-system -l k8s-app=kube-proxy |
| Vérifier CoreDNS | Quotidien | kubectl get pods -n kube-system -l k8s-app=kube-dns |
| Tester la résolution DNS | Hebdomadaire | kubectl run ... nslookup |
| Passer en revue les politiques réseau | Mensuel | kubectl get networkpolicies --all-namespaces |
| Valider les endpoints des services | Hebdomadaire | kubectl get endpoints --all-namespaces |
| Connectivité entre pods inter-nœuds | Hebdomadaire | kubectl exec pod-a -- ping pod-b-ip |
| Revue des journaux CNI | Quotidien | kubectl logs -n kube-system -l k8s-app=calico-node --tail=20 |
Pour chaque élément, documentez le résultat attendu et configurez des alertes pour les écarts à l'aide d'outils de surveillance comme Prometheus.
Conclusion
Le dépannage du réseau Kubernetes nécessite une approche méthodique : rassembler les détails de l'environnement, apporter des modifications de configuration sûres, vérifier avec des commandes concrètes, comprendre les modes de défaillance et suivre une liste de contrôle opérationnelle. Les exemples de ce guide fournissent une base pour diagnostiquer et résoudre les problèmes courants. Commencez par une portée pilote, conservez des sauvegardes et vérifiez toujours avant et après les modifications. Avec ces pratiques, vous pouvez maintenir un réseau Kubernetes fiable et performant.
N'oubliez pas que le réseau est un système en couches. Les problèmes peuvent survenir au niveau de la couche DNS, de la couche d'abstraction des services, de l'implémentation de kube-proxy ou du plan de données CNI. Une approche d'élimination systématique, en commençant par le DNS puis en passant à la connectivité des pods et des services, révèle souvent rapidement la cause profonde. Corrélez toujours les journaux et les événements de plusieurs composants, et en cas de doute, isolez le problème en testant depuis différents espaces de noms ou nœuds. En construisant une boîte à outils de diagnostic robuste et en suivant les pratiques de modification sûre décrites ici, vous pouvez minimiser les temps d'arrêt et garder vos applications accessibles.