Aller au contenu
Conteneurs & Orchestration medium

Pod Networking, Communication réseau entre Pods

23 min de lecture

Kubernetes définit un modèle réseau où chaque Pod possède sa propre IP et peut joindre les autres Pods du cluster directement, sans avoir à publier de ports comme avec Docker. L'implémentation concrète dépend du plugin CNI, mais le modèle garantit une communication transparente entre Pods. Contrairement à Docker où les conteneurs partagent l'IP de l'hôte et utilisent le port mapping, Kubernetes crée un réseau plat : chaque Pod possède son propre espace de noms réseau (network namespace), donc sa propre pile réseau et la totalité des 65 535 ports, sans jamais entrer en conflit avec un autre Pod du même nœud.

Ce guide couvre le domaine Services & Networking (20%) de la certification CKA.

  • Le modèle réseau Kubernetes et ses garanties
  • Comment un Pod obtient son adresse IP
  • La communication Pod-to-Pod sur le même nœud et entre nœuds
  • Le rôle du CNI et du kube-proxy
  • Les commandes de diagnostic réseau

Le modèle réseau est un contrat écrit dans la spécification Kubernetes : il énonce ce qui doit être vrai du réseau, sans dire comment l'obtenir. Cette séparation explique pourquoi deux clusters au comportement identique pour vos applications peuvent reposer sur des technologies radicalement différentes, du tunnel VXLAN au routage BGP. Comprendre le contrat avant l'implémentation évite de confondre un problème d'application avec un problème de plugin CNI.

Kubernetes doit résoudre 4 types de communication, du plus local au plus exposé. Les deux premiers relèvent du réseau des Pods traité ici, les deux suivants passent par les Services et sont couverts par d'autres pages du parcours.

TypeDescriptionSolution
Container-to-ContainerConteneurs dans le même Podlocalhost (127.0.0.1)
Pod-to-PodPods dans le clusterRéseau Pod (ce guide)
Pod-to-ServicePod vers un Servicekube-proxy + DNS
External-to-ServiceTrafic externe vers le clusterIngress, LoadBalancer

Kubernetes impose trois règles fondamentales que tout plugin CNI doit respecter pour être conforme. Elles ont une conséquence directe sur vos applications : une adresse IP relevée dans un log correspond bien au Pod émetteur, sans traduction d'adresse (NAT) qui la remplacerait par celle du nœud. C'est ce qui rend exploitables les journaux d'accès et les règles de filtrage basées sur l'IP source.

  1. Chaque Pod reçoit sa propre adresse IP
  2. Les Pods peuvent communiquer entre eux sans port mapping, quel que soit le nœud, l'IP vue par le Pod source correspond à l'IP réelle du Pod destination
  3. L'IP vue par un Pod est la même que celle vue par les autres Pods (pas de SNAT entre Pods)

Le schéma ci-dessous montre les deux niveaux d'adressage qui coexistent dans un cluster : l'IP du nœud (192.168.1.x, celle de la machine physique ou virtuelle) et l'IP du Pod (10.244.x.x, distribuée par le plugin CNI). Retenez que les Pods d'un même nœud partagent un point de raccordement local, et que ce sont les nœuds qui se chargent du transport entre eux.

┌─────────────────────────────────────────────────────────────────────────┐
│ Cluster Kubernetes │
│ │
│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │
│ │ Node 1 │ │ Node 2 │ │
│ │ IP: 192.168.1.10 │ │ IP: 192.168.1.11 │ │
│ │ │ │ │ │
│ │ ┌─────────┐ ┌─────────┐ │ │ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Pod A │ │ Pod B │ │ │ │ Pod C │ │ Pod D │ │ │
│ │ │10.244. │ │10.244. │ │ │ │10.244. │ │10.244. │ │ │
│ │ │ 1.5 │ │ 1.12 │ │ │ │ 2.7 │ │ 2.19 │ │ │
│ │ └────┬────┘ └────┬────┘ │ │ └────┬────┘ └────┬────┘ │ │
│ │ │ │ │ │ │ │ │ │
│ │ └─────┬─────┘ │ │ └─────┬─────┘ │ │
│ │ │ │ │ │ │ │
│ │ ┌──────┴──────┐ │ │ ┌──────┴──────┐ │ │
│ │ │ CNI bridge │ │ │ │ CNI bridge │ │ │
│ │ │ ou fabric │ │ │ │ ou fabric │ │ │
│ │ └──────┬──────┘ │ │ └──────┬──────┘ │ │
│ │ │ │ │ │ │ │
│ └─────────────┼──────────────┘ └─────────────┼──────────────┘ │
│ │ │ │
│ └──────────────┬───────────────────┘ │
│ │ │
│ ┌──────────┴──────────┐ │
│ │ Réseau physique │ │
│ │ ou overlay │ │
│ └─────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────┘

Les adresses des Pods ne sont pas tirées au hasard : elles proviennent d'une plage réservée au cluster, découpée en sous-réseaux distribués nœud par nœud. Ce découpage est ce qui permet de router le trafic sans consulter un annuaire central, puisque le préfixe de l'adresse suffit à désigner le nœud de destination. Une plage mal dimensionnée ou en conflit avec le réseau de l'entreprise est une cause classique de cluster inutilisable, et elle se corrige difficilement après coup.

Le cluster définit une plage d'adresses IP réservée aux Pods via le Pod CIDR :

Fenêtre de terminal
# Voir le CIDR du cluster (méthode kubeadm)
kubectl cluster-info dump | grep -m 1 cluster-cidr

Configuration typique :

ParamètreValeur exempleDescription
--cluster-cidr10.244.0.0/16Plage totale pour les Pods
--node-cidr-mask-size/24Taille du sous-réseau par nœud

Chaque nœud reçoit un sous-réseau du CIDR cluster :

Fenêtre de terminal
# Voir le CIDR alloué à chaque nœud
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.podCIDR}{"\n"}{end}'
master1 10.244.0.0/24
worker1 10.244.1.0/24
worker2 10.244.2.0/24

Le plugin CNI est responsable de l'allocation IP via son composant IPAM (IP Address Management, le module qui tient le registre des adresses prises et libres). Ni l'API server ni le kubelet ne choisissent l'adresse : ils la reçoivent du plugin et se contentent de la publier dans le champ status.podIP du Pod. La chaîne d'appels ci-dessous est utile en dépannage, car elle indique où chercher les traces quand un Pod reste bloqué sans adresse.

Pod créé
kubelet appelle le runtime (CRI)
Runtime crée le namespace réseau
Runtime appelle le plugin CNI
CNI IPAM alloue une IP du CIDR du nœud
CNI configure l'interface veth + routes
Pod prêt avec son IP

L'adresse n'apparaît pas dans la sortie par défaut de kubectl get pods : il faut demander -o wide, -o jsonpath ou des colonnes personnalisées. Un Pod qui n'a pas encore terminé son démarrage renvoie une valeur vide, ce qui est normal tant que le CNI n'a pas répondu.

Fenêtre de terminal
# IP dans la description
kubectl get pod <name> -o wide
# IP via jsonpath
kubectl get pod <name> -o jsonpath='{.status.podIP}'
# IPs de tous les Pods
kubectl get pods -A -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name,IP:.status.podIP

Du point de vue de votre application, joindre un autre Pod revient à ouvrir une connexion vers son IP : rien à configurer, rien à publier. Sous le capot, le chemin emprunté par le paquet change radicalement selon que les deux Pods tournent sur le même nœud ou non. Cette différence explique pourquoi une application peut fonctionner sur un cluster à un seul nœud et échouer dès qu'elle est répartie sur plusieurs machines.

Quand deux Pods sont sur le même nœud, ils communiquent via un bridge virtuel :

┌─────────────────────────────────────────────────┐
│ Node │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Pod A │ │ Pod B │ │
│ │ 10.244. │ │ 10.244. │ │
│ │ 1.5 │ │ 1.12 │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ veth │ veth │
│ │ │ │
│ └───────────┬─────────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ CNI bridge │ (interface gérée │
│ │ ou fabric │ par le plugin) │
│ └─────────────┘ │
│ │
└──────────────────────────────────────────────────┘

Le paquet reste local au nœud, aucun trafic ne sort sur le réseau physique.

Quand les Pods sont sur des nœuds différents, le trafic doit traverser le réseau :

Le CNI encapsule le paquet Pod dans un paquet UDP :

┌─────────────────────────────────────────────────────────────────┐
│ Paquet original │
│ Src: 10.244.1.5 (Pod A) → Dst: 10.244.2.7 (Pod C) │
└─────────────────────────────────────────────────────────────────┘
▼ Encapsulation VXLAN
┌─────────────────────────────────────────────────────────────────┐
│ Outer IP: Src 192.168.1.10 → Dst 192.168.1.11 │
│ UDP Port 4789 (VXLAN) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Inner: Src 10.244.1.5 → Dst 10.244.2.7 │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

Utilisé par : Flannel (mode vxlan), Calico (mode VXLAN), Cilium (mode overlay)

kube-proxy ne gère pas la communication Pod-to-Pod directe. Son rôle est de :

  • Implémenter les Services (ClusterIP, NodePort, LoadBalancer)
  • Configurer les règles iptables ou IPVS pour router vers les Pods backend
Pod A veut contacter Service "nginx" (ClusterIP 10.96.1.100)
iptables/IPVS (kube-proxy)
NAT vers un Pod backend (10.244.2.15)
Communication Pod-to-Pod normale

Vérifier le réseau demande deux Pods réellement en cours d'exécution : il n'existe pas de commande kubectl qui teste le chemin réseau sans trafic. La méthode consiste donc à lancer des Pods jetables, à relever leurs adresses puis à provoquer un échange depuis l'un vers l'autre. Placez ces Pods sur des nœuds différents si vous voulez éprouver le chemin inter-nœuds, sinon le test restera local et ne prouvera rien sur l'overlay.

Ce test enchaîne création, relevé des adresses, échange puis nettoyage. Pensez à supprimer les Pods à la fin : lancés avec sleep infinity, ils tournent indéfiniment et consomment des ressources.

  1. Créez deux Pods de test

    Fenêtre de terminal
    kubectl run test1 --image=busybox --command -- sleep infinity
    kubectl run test2 --image=busybox --command -- sleep infinity
  2. Récupérez les IPs

    Fenêtre de terminal
    kubectl get pods -o wide
    NAME READY STATUS IP NODE
    test1 1/1 Running 10.244.1.5 worker1
    test2 1/1 Running 10.244.2.8 worker2
  3. Testez la connectivité

    Fenêtre de terminal
    # Depuis test1, ping test2
    kubectl exec test1 -- ping -c 3 10.244.2.8
  4. Nettoyez

    Fenêtre de terminal
    kubectl delete pod test1 test2

Un échange HTTP vaut mieux qu'un ping : il traverse la même pile TCP que vos applications et n'est pas filtré par les règles ICMP. L'option --rm supprime le Pod de test dès la fin de la commande, ce qui évite d'oublier un Pod Completed dans le namespace.

Fenêtre de terminal
# Créer un serveur nginx
kubectl run nginx --image=nginx
kubectl expose pod nginx --port=80
# Tester depuis un autre Pod
kubectl run test --rm -it --image=busybox -- wget -qO- nginx

Quand l'échange échoue, la question suivante est de savoir si le Pod a bien reçu une interface et une route par défaut. Les deux premières commandes s'exécutent dans le Pod et supposent une image contenant ip (busybox et nicolaka/netshoot en disposent, pas nginx) ; la troisième s'exécute directement sur le nœud, en root.

Fenêtre de terminal
# Voir les interfaces réseau dans un Pod
kubectl exec <pod> -- ip addr
# Voir la table de routage
kubectl exec <pod> -- ip route
# Voir les règles iptables du nœud (depuis le nœud)
iptables -t nat -L -n -v | head -50

La grande majorité des pannes réseau d'un cluster se ramène à trois situations : le plugin CNI n'est pas installé ou plante, l'allocation d'adresse échoue, ou le trafic entre nœuds est bloqué par le réseau sous-jacent. Chaque cas se reconnaît à un symptôme distinct, et les commandes de diagnostic diffèrent. Traitez-les dans cet ordre, car un CNI absent rend tous les autres tests inutiles.

Ce symptôme couvre aussi bien un CNI défaillant qu'une Network Policy trop restrictive. Commencez par confirmer que les Pods du plugin réseau tournent dans kube-system avant de suspecter votre application.

Symptômes : ping timeout ou "Network unreachable"

Diagnostic :

Fenêtre de terminal
# 1. Vérifier que le CNI est installé
kubectl get pods -n kube-system | grep -E 'calico|cilium|flannel'
# 2. Vérifier les logs CNI
kubectl logs -n kube-system -l k8s-app=calico-node
# 3. Vérifier les routes sur le nœud
ip route | grep 10.244

Solutions possibles :

  • Installer un plugin CNI si absent
  • Vérifier les Network Policies qui pourraient bloquer
  • Redémarrer le DaemonSet CNI

Un Pod coincé dans cet état attend que quelque chose se termine, et l'attribution d'adresse par le CNI en fait partie. Les événements du Pod portent le message d'erreur exact renvoyé par le plugin, c'est le premier endroit à consulter.

Cause fréquente : Erreur CNI lors de l'allocation IP

Fenêtre de terminal
# Voir les événements du Pod
kubectl describe pod <name> | grep -A5 Events
# Vérifier les logs kubelet
journalctl -u kubelet | grep -i cni

Quand deux Pods se joignent sur un même nœud mais pas entre nœuds, la cause est presque toujours en dehors de Kubernetes : port UDP 4789 fermé pour VXLAN, protocole IP 4 filtré pour IP-in-IP, ou session BGP non établie. Les commandes suivantes confirment d'abord que le cluster a bien distribué les sous-réseaux, puis que le nœud sait par où sortir.

Vérifications :

Fenêtre de terminal
# Les nœuds se voient-ils ?
kubectl get nodes
# Le CIDR est-il correctement alloué ?
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.podCIDR}{"\n"}{end}'
# Route vers l'autre sous-réseau Pod
ip route get 10.244.2.1

L'épreuve CKA est chronométrée et se joue au terminal : ces commandes couvrent l'essentiel des questions réseau du domaine Services & Networking. Entraînez-vous à les taper sans consulter la documentation, en particulier les expressions jsonpath qui sont les plus longues à reconstituer sous pression.

Fenêtre de terminal
# Voir l'IP d'un Pod
kubectl get pod <name> -o wide
# CIDR par nœud
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.podCIDR}{"\n"}{end}'
# Interfaces dans un Pod
kubectl exec <pod> -- ip addr
# Routes dans un Pod
kubectl exec <pod> -- ip route
# Test de connectivité
kubectl exec <pod1> -- ping -c 2 <pod2-ip>
# DNS test (Pod-to-Service)
kubectl exec <pod> -- nslookup kubernetes.default
# Vérifier le CNI
ls /etc/cni/net.d/
kubectl get pods -n kube-system | grep -E 'calico|cilium|flannel|ovn'
  1. Chaque Pod a sa propre IP, pas de port mapping nécessaire
  2. Modèle réseau = contrat, Kubernetes définit les garanties, le CNI implémente
  3. Le CNI configure le réseau et attribue les IPs
  4. Pod CIDR divisé en sous-réseaux par nœud
  5. Overlay (VXLAN) ou native routing (BGP) pour le trafic inter-nœuds
  6. kube-proxy gère les Services, pas le routage Pod-to-Pod direct
  7. Les conteneurs d'un même Pod communiquent via localhost

Ce questionnaire reprend les points du guide dans le format des questions CKA. Le seuil de réussite est fixé à 70 %, comme à l'examen.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

10 questions
8 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn