Introduction
Le réseau Kubernetes couvre la résolution de noms, le routage des services, les overlays de pods, iptables ou IPVS sur les nœuds, le DNS du cluster, les NetworkPolicy, ainsi que les pare-feu cloud ou sur site. Lorsque le trafic casse, deviner fait perdre du temps et risque de perturber davantage. Ce guide propose une méthode reproductible pour isoler les défaillances, valider les résultats attendus et récupérer rapidement. Il inclut des commandes concrètes, des charges de test contrôlées et des étapes de retour arrière.
Ce que vous obtiendrez :
- Un inventaire d'environnement réutilisable
- Un espace de noms de test sûr avec une charge d'écho pour sonder les chemins courants
- Une séquence diagnostique du DNS jusqu'au pod, service, nœud et trafic sortant
- Sorties attendues, modes de défaillance et étapes de récupération ciblées
- Une liste de contrôle opérationnelle concise pour un usage continu
Portée : Cet article se concentre sur le dépannage. Il ne prescrit pas de CNI (Container Network Interface) spécifique (Calico, Cilium, Flannel, etc.) mais montre comment interroger celui que vous exécutez.
Inventaire des versions et de l'environnement
Avant de changer quoi que ce soit, enregistrez l'état actuel. Cela évite les erreurs de diagnostic et permet un retour arrière rapide.
Prérequis :
- Accès
kubectlavec permissions de lecture sur tous les espaces de noms etkube-system - Accès SSH optionnel aux nœuds pour des vérifications en lecture seule (listes iptables, routes). Ignorez si indisponible.
Capturez les versions et modes :
kubectl version -o yaml | sed -n '1,80p'
kubectl cluster-info
kubectl get nodes -o wide
kubectl get pods -A -o wide
kubectl -n kube-system get cm kube-proxy -o yaml | grep -i mode -n || true
kubectl -n kube-system get pods -l k8s-app=kube-dns
kubectl -n kube-system get svc -l k8s-app=kube-dns -o wide || \
kubectl -n kube-system get svc -l k8s-app=coredns -o wide
Si vous avez un accès aux nœuds, capturez l'état du routage et du pare-feu (listes uniquement) :
# Sur un nœud (lecture seule)
sudo ip route
sudo iptables -S | head -n 50
sudo iptables -L -n | head -n 50
# Si IPVS (IP Virtual Server) est utilisé
sudo ipvsadm -Ln 2>/dev/null | head -n 50 || true
Enregistrez votre plugin CNI (Container Network Interface) et son statut :
kubectl -n kube-system get pods -o wide | egrep -i 'calico|cilium|flannel|weave|antrea' || true
kubectl -n kube-system logs deploy/coredns --tail=100 || \
kubectl -n kube-system logs -l k8s-app=kube-dns --tail=100
Astuce : Notez les réglages MTU (Maximum Transmission Unit) sur les interfaces des nœuds et dans la configuration du CNI. Un désaccord MTU cause souvent des échecs intermittents ou sur de grosses charges utiles.
Chemin de configuration sûr
Utilisez un espace de noms temporaire et des charges minimales que vous pouvez supprimer rapidement.
Principes :
- Contenez tous les tests dans un espace de noms (par exemple
net-test) - Privilégiez d'abord les commandes en lecture seule non perturbatrices
- Quand vous ajoutez des politiques ou routes pour tester, documentez et prévoyez un chemin de suppression clair
Créez l'espace de noms de test et deux mini applications d'écho :
kubectl create namespace net-test
# Serveur d'écho HTTP et Service
cat <<'YAML' | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: echo-a
namespace: net-test
labels:
app: echo-a
spec:
containers:
- name: http-echo
image: hashicorp/http-echo:0.2.3
args: ["-text=hello-from-echo-a"]
ports:
- containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
name: echo-a
namespace: net-test
spec:
selector:
app: echo-a
ports:
- name: http
port: 80
targetPort: 5678
YAML
# Pod de test busybox pour curl, nslookup, ping
kubectl -n net-test run net-debug --image=busybox:1.36 --restart=Never -- sleep 36000
kubectl -n net-test wait --for=condition=ready pod/echo-a --timeout=90s || true
kubectl -n net-test get pods -o wide
Résultats attendus :
- Le pod
echo-aest Running et Ready ; le Service a un ClusterIP - Le pod
net-debugest Running
Retour arrière : Supprimez tous les artefacts de test avec kubectl delete ns net-test.
Vérification et diagnostics
Procédez des vérifications les plus simples à celles nécessitant plus d'accès. Arrêtez-vous au premier saut qui échoue.
1) Bases du DNS à l'intérieur du cluster
Depuis le pod net-debug, testez la découverte de service et le DNS du cluster.
# Entrez dans le pod
kubectl -n net-test exec -it net-debug -- sh
# À l'intérieur du pod
nslookup kubernetes.default.svc.cluster.local
nslookup echo-a.net-test.svc.cluster.local
Attendu : Les deux noms se résolvent en ClusterIP. Les échecs indiquent des problèmes de DNS ou de chemin de recherche.
Si la résolution de nom échoue :
- Vérifiez le statut et les logs des pods CoreDNS/Kube-DNS
- Assurez-vous que le pod
net-debuga/etc/resolv.confpointant vers l'IP du service DNS du cluster
Commandes :
# De retour à l'extérieur du pod
kubectl -n kube-system get pods -l k8s-app=kube-dns -o wide || \
kubectl -n kube-system get pods -l k8s-app=coredns -o wide
kubectl -n kube-system logs -l k8s-app=k8s-dns --tail=200 || \
kubectl -n kube-system logs -l k8s-app=coredns --tail=200
kubectl -n net-test exec net-debug -- cat /etc/resolv.conf
Signaux typiques :
SERVFAILou timeout : service DNS inaccessible ou plugins CoreDNS mal configurésNXDOMAINpour les noms de service : problèmes du plugin Kubernetes DNS ou domaines de recherche incorrects
2) Chemin Pod vers Service (ClusterIP)
Depuis net-debug, lancez un curl vers le service echo-a par DNS et par IP.
# À l'intérieur de net-debug
wget -qO- http://echo-a
wget -qO- http://<ECHO_A_CLUSTER_IP>
Attendu : Texte de réponse hello-from-echo-a.
Si le DNS fonctionne mais l'IP échoue : les règles kube-proxy ou le routage CNI peuvent être cassés.
Vérifiez le mode kube-proxy et ses règles :
# À l'extérieur
kubectl -n kube-system get cm kube-proxy -o yaml | grep -i mode -n || true
# Sur un nœud (lecture seule) : attendez des chaînes KUBE- pour le mode iptables
sudo iptables-save | egrep 'KUBE-SVC|KUBE-SEP' | head -n 20 || true
sudo ipvsadm -Ln | head -n 20 || true
3) Connectivité Pod-à-Pod (même nœud et inter-nœuds)
Trouvez l'IP du pod echo-a et ping/curl directement.
kubectl -n net-test get pod -o wide -l app=echo-a
# À l'intérieur de net-debug
PING_IP=$(kubectl -n net-test get pod -l app=echo-a -o jsonpath='{.items[0].status.podIP}')
ping -c2 $PING_IP || true
wget -qO- http://$PING_IP:5678
Attendu :
- Les pings peuvent être bloqués par une politique ICMP ; le succès est informatif mais l'échec n'est pas concluant
- HTTP doit réussir. Sinon, suspectez CNI, NetworkPolicy ou routes
4) Vérifications NetworkPolicy
Listez les politiques dans l'espace de noms et testez les autorisations.
kubectl -n net-test get networkpolicy
Pour valider les effets de politique, appliquez un défaut-refus puis une règle d'autorisation, puis annulez :
# Refus par défaut tout trafic entrant
cat <<'YAML' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: net-test
spec:
podSelector: {}
policyTypes:
- Ingress
YAML
# Autorise net-debug vers echo-a
cat <<'YAML' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-debug-to-echo
namespace: net-test
spec:
podSelector:
matchLabels:
app: echo-a
ingress:
- from:
- podSelector:
matchLabels:
run: net-debug
YAML
Attendu :
- Avec
default-denyappliqué, le curl depuisnet-debugversecho-adoit échouer par timeout - Avec la règle d'autorisation, le curl doit à nouveau réussir
Retour arrière :
kubectl -n net-test delete networkpolicy default-deny allow-debug-to-echo --ignore-not-found
5) NodePort et accès externe
Si la charge doit être accessible en externe via NodePort, exposez-la et testez depuis l'extérieur du cluster.
kubectl -n net-test expose pod echo-a --type=NodePort --name=echo-a-nodeport --port=80 --target-port=5678
kubectl -n net-test get svc echo-a-nodeport -o wide
Depuis un poste de travail ou un autre nœud :
# Remplacez NODE_IP et NODEPORT en conséquence
curl -sS http://NODE_IP:NODEPORT
Si cela échoue alors que ClusterIP fonctionne : vérifiez le pare-feu du nœud ou les groupes de sécurité cloud pour la plage NodePort (par défaut 30000-32767/TCP).
6) Sortie vers Internet (egress)
Depuis net-debug, testez le DNS externe et HTTP.
# À l'intérieur de net-debug
nslookup example.com
wget -qO- https://ifconfig.me || wget -qO- http://ifconfig.me || true
Si le DNS vers Internet échoue mais le DNS du cluster fonctionne : vos forwarders DNS du cluster ou résolveurs amont peuvent être bloqués. Si l'egress HTTP échoue, vérifiez la passerelle NAT, les passerelles d'egress ou les tables de routage cloud.
7) MTU et fragmentation
Un désaccord MTU jumbo ou overlay cause des pertes silencieuses pour les gros paquets.
# À l'intérieur de net-debug, choisissez une IP externe accessible (exemple 1.1.1.1)
ping -s 1472 -M do -c 2 1.1.1.1 || true
ping -s 1200 -M do -c 2 1.1.1.1 || true
Attendu : Une charge utile plus grande peut échouer alors qu'une plus petite passe. Si c'est le cas, alignez le MTU entre les interfaces des nœuds et l'overlay CNI. Pour les overlays VXLAN, un correctif courant est de régler le MTU CNI à 1450 quand l'interface du nœud est à 1500.
8) Vérification de la configuration CoreDNS
Vérifiez le ConfigMap CoreDNS pour des réécritures ou upstreams inhabituels.
kubectl -n kube-system get configmap coredns -o yaml
Cherchez :
- Plugins loop ou rewrite lourds
- Résolveurs amont inaccessibles depuis les nœuds du cluster
- Configuration du plugin cache trop agressive
9) Observabilité avec événements et logs
Des gains rapides viennent souvent des événements et logs ciblés.
kubectl get events -A --sort-by=.lastTimestamp | tail -n 30
kubectl -n kube-system logs -l k8s-app=kube-proxy --tail=200
# Pour votre CNI, exemples de sélecteurs (peuvent différer) :
kubectl -n kube-system logs -l k8s-app=calico-node --tail=200 || true
kubectl -n kube-system logs -l k8s-app=cilium --tail=200 || true
Chemins réseau courants et où regarder
Utilisez cette référence pour mapper les symptômes aux composants :
- Pod -> Service ClusterIP — Test depuis le pod ; composants principaux : kube-proxy, routage CNI ; zone de correctif typique : règles kube-proxy, disponibilité CNI
- Pod -> Pod (même nœud) — Test depuis le pod ; composants principaux : veth/bridge CNI ; zone de correctif typique : sandbox pod, CNI, politique
- Pod -> Pod (inter-nœuds) — Test depuis le pod ; composants principaux : overlay CNI, routes nœud ; zone de correctif typique : routage nœud, MTU, démon CNI
- Pod -> Internet (egress) — Test depuis le pod ; composants principaux : NAT/passerelle d'egress, routes ; zone de correctif typique : passerelles NAT, pare-feu, politique d'egress
- Externe -> NodePort — Test depuis le poste de travail ; composants principaux : pare-feu nœud, kube-proxy ; zone de correctif typique : pare-feu nœud, groupes de sécurité
Modes de défaillance et récupération
La liste ci-dessous mappe les symptômes courants à des étapes de récupération concrètes et des retours arrière. Adaptez les valeurs à votre environnement.
Symptôme : Timeout DNS du service
- Cause probable : CoreDNS en panne ou inaccessible
- Vérification :
kubectl -n kube-system get pods -l k8s-app=coredns - Récupération : Redémarrez ou scalez CoreDNS ; assurez-vous que l'IP du service DNS est accessible depuis les pods
- Retour arrière : Annulez toute modification du ConfigMap CoreDNS
Symptôme : NXDOMAIN pour le nom de service
- Cause probable : Mauvais domaines de recherche ou plugin
- Vérification :
kubectl -n net-test exec net-debug -- cat /etc/resolv.conf - Récupération : Corrigez le suffixe de recherche ; corrigez les plugins CoreDNS
- Retour arrière : Restaurez le ConfigMap précédent
Symptôme : ClusterIP curl échoue, IP du pod fonctionne
- Cause probable : Tables kube-proxy cassées
- Vérification :
iptables-save | grep KUBE-SVCouipvsadm -Ln - Récupération : Redémarrez le DaemonSet kube-proxy ; réconciliez la config
- Retour arrière : Annulez le changement de config kube-proxy
Symptôme : Accessibilité pod inter-nœuds échoue
- Cause probable : CNI pas prêt ou désaccord MTU
- Vérification :
kubectl -n kube-system logs <démon-cni>; test MTU - Récupération : Redémarrez le DaemonSet CNI ; alignez MTU
- Retour arrière : Restaurez la config CNI précédente
Symptôme : NodePort inaccessible en externe
- Cause probable : Pare-feu nœud / groupe de sécurité bloque
- Vérification :
curl NODE_IP:NODEPORTdepuis l'extérieur ; vérifiez le groupe de sécurité - Récupération : Ouvrez la plage NodePort ; autorisez le groupe de sécurité du nœud
- Retour arrière : Annulez le changement pare-feu/groupe de sécurité
Symptôme : DNS egress fonctionne, HTTP échoue
- Cause probable : Problème de route NAT/egress
- Vérification :
wget -qO- ifconfig.meéchoue - Récupération : Corrigez la passerelle NAT / SNAT ; corrigez les routes
- Retour arrière : Annulez les modifications de route/NAT
Symptôme : Pertes intermittentes de grosses charges utiles
- Cause probable : Fragmentation MTU bloquée
- Vérification :
ping -M do -s 1472échoue ; plus petit fonctionne - Récupération : Baissez le MTU overlay ; activez la découverte MTU de chemin
- Retour arrière : Annulez le changement MTU si inefficace
Notes de retour arrière et sécurité
- Appliquez toujours les changements à l'espace de noms
net-testou hors production d'abord - Sauvegardez les ConfigMaps et l'état iptables/IPVS avant modifications :
kubectl -n kube-system get cm coredns -o yaml > coredns.bak.yaml
sudo iptables-save > iptables-$(date +%s).bak
- Pour les expériences NetworkPolicy, supprimez les politiques pour restaurer le comportement précédent :
kubectl -n net-test delete networkpolicy --all
- Pour les changements CNI, prévoyez un plan de vidage et de remise en service progressif des nœuds ; soyez prêt à revenir à l'image ou config DaemonSet antérieure
Ports et composants à connaître
Référence rapide pour le pare-feu entre nœuds, plan de contrôle et pods (adaptez à votre configuration) :
- kube-apiserver — TCP/6443 — API du plan de contrôle
- kubelet — TCP/10250 — API kubelet du nœud
- CoreDNS — UDP/53, TCP/53 — DNS du cluster
- Plage NodePort — TCP/30000-32767 — Accès externe aux Services
- etcd (si autogéré) — TCP/2379-2380 — Stockage du plan de contrôle
Résumé de la vérification
Après chaque correctif, relancez le jeu de tests minimal pour confirmer la récupération et éviter les régressions :
- DNS dans les pods :
kubectl -n net-test exec net-debug -- nslookup echo-a.net-test.svc.cluster.local
- Routage ClusterIP :
kubectl -n net-test exec net-debug -- wget -qO- http://echo-a
- IP du pod directe :
ECHO_IP=$(kubectl -n net-test get pod -l app=echo-a -o jsonpath='{.items[0].status.podIP}')
kubectl -n net-test exec net-debug -- wget -qO- http://$ECHO_IP:5678
- Externe optionnel :
curl -sS http://NODE_IP:NODEPORT || true
Attendu : Toutes les étapes précédemment en échec passent maintenant.
Liste de contrôle opérationnelle
Utilisez cette liste concise lors des incidents et des vérifications de routine.
- Capturez l'inventaire
kubectl version,cluster-info,nodes -o wide- mode kube-proxy ; pods et logs CNI
- Notez l'IP du service DNS et le statut CoreDNS
- Préparez un périmètre de test sûr
- Créez l'espace de noms
net-test - Déployez les pods
echo-aetnet-debug - Confirmez la disponibilité
- Exécutez les diagnostics dans l'ordre
- DNS dans le pod :
nslookup kubernetesetecho-a - HTTP Service via DNS et ClusterIP
- Accès direct IP du pod
- Présence et effets NetworkPolicy
- NodePort depuis l'extérieur (si pertinent)
- DNS et HTTP egress
- Vérifications MTU si symptômes correspondent
- Identifiez le domaine de défaillance
- DNS vs proxy/routage vs politique vs pare-feu vs MTU
- Appliquez un correctif ciblé
- Modifiez ConfigMap, politique, pare-feu, ou CNI/kube-proxy selon l'indication
- Vérifiez et retour arrière si nécessaire
- Relancez les tests de base
- Si pas d'amélioration, annulez le dernier changement proprement
- Nettoyez
- Supprimez l'espace de noms
net-testquand fini - Archivez logs et commandes pour revue post-incident
Conclusion
Les problèmes de réseau Kubernetes deviennent traitables quand on les aborde méthodiquement. Commencez par inventorier les versions, modes et statut CNI. Utilisez un espace de noms temporaire sûr et une charge de test minimale pour sonder le DNS, le routage Service, les chemins de pods, NodePort et l'egress. Comparez les sorties aux résultats attendus pour identifier la couche en échec. Quand vous faites des changements, gardez-les limités et réversibles, vérifiez les correctifs immédiatement, et annulez si les résultats ne s'améliorent pas. Avec les commandes, exemples et listes de contrôle de ce guide, vous pouvez diagnostiquer et récupérer de la plupart des incidents réseau de cluster avec confiance et reproductibilité.