DEV Community

James Lee
James Lee

Posted on

Kubernetes Data Access Flow: How Network Traffic Moves Inside and Outside the Cluster

In the previous article we saw how kubelet orchestrates storage, network, and compute resources to bring a Pod to life. Now let's trace what happens when that Pod actually sends and receives data — following packets hop by hop through virtual ethernet devices, CNI bridges, and Flannel overlays.

Network solution context: Kubernetes supports multiple CNI plugins (Calico, Cilium, Flannel, Weave Net, Contiv-VPP, Kube-router). This article uses Flannel as the reference implementation — it's the most representative for understanding the underlying data flow.


Overview: 6 Traffic Scenarios

# Scenario Crosses host boundary? Crosses cluster boundary?
1 Container → Container (same Pod)
2 Pod → Pod (same host)
3 Host → Pod (same host)
4 Pod → Pod (different hosts)
5 External app → Pod
6 Pod → External app

Scenario 1: Container → Container (Same Pod)

All containers in a Pod share one network namespace — they communicate via the shared Linux network stack, never touching the host.

Container 0                    Container n
┌──────────────┐               ┌──────────────┐
│    App       │               │    App       │
│    Veth0     │               │    Veth0     │
└──────┬───────┘               └──────┬───────┘
       │                              │
     Vethx ◄──── Pod Shared ────► Vethy
                Network Stack
               (shared netns)
Enter fullscreen mode Exit fullscreen mode

Step-by-step:

① Container 0 sends request via its Veth0
② Veth0's peer Vethx receives data
   → passes through Pod's shared network stack
③ Vethy (peer of Container n's Veth0) receives data
   → forwards to Container n's Veth0
④ Container n receives the request  ✅

Response follows the reverse path.
Enter fullscreen mode Exit fullscreen mode

Key insight: Intra-Pod communication is essentially localhost traffic. Containers share the same IP and communicate via port numbers, just like processes on the same machine.


Scenario 2: Pod → Pod (Same Host)

When two Pods are on the same node, traffic flows through the CNI0 bridge — a virtual Layer 2 switch that connects all Pods on the node.

Source Host
┌──────────────────────────────────────────────────────────┐
│                                                          │
│  Source Pod              CNI0 Bridge      Target Pod    │
│  ┌──────────┐           ┌─────────┐      ┌──────────┐   │
│  │Container0│           │  Vethc  │      │Container0│   │
│  │  Veth0   │           │  Vethd  │      │  Veth0   │   │
│  └────┬─────┘           └────┬────┘      └────┬─────┘   │
│       │                      │                │         │
│     Vetha                  bridge           Vethf       │
│  (shared netns)         (L2 switch)      (shared netns) │
│     Vethb ──────────► Vethc                Vethe        │
│                        Vethd ──────────► Vethe          │
│                                           Vethf         │
└──────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Step-by-step:

① Container 0 (src) sends via Veth0
② Veth0's peer Vetha receives → passes through src Pod shared netns
③ Vethb sends data out of src Pod netns
④ Vethc (Vethb's peer on CNI0 bridge) receives
   → CNI0 bridge forwards to target Pod direction
⑤ Vethd on CNI0 bridge sends toward target Pod
⑥ Vethe (Vethd's peer in target Pod netns) receives
⑦ Vethf (peer of target Container 0's Veth0) forwards data
⑧ Target Container 0's Veth0 receives  ✅

Response follows the reverse path.
Enter fullscreen mode Exit fullscreen mode

Scenario 3: Host → Pod (Same Host)

When the node itself needs to communicate with a Pod running on it (e.g., kubelet health checks, host-level monitoring):

Host Network Stack
┌──────────────────────────────────────────────────────────┐
│                                                          │
│  Host Process                                            │
│      │                                                   │
│      ▼                                                   │
│  Host routing table                                      │
│      │ (route to Pod CIDR → Flannel.1)                   │
│      ▼                                                   │
│  Flannel.1 (virtual bridge)                              │
│      │                                                   │
│    Vetha ──────────────────────────────────────────────► │
│                                                          │
│              CNI0 Bridge                                 │
│              Vethb (Vetha's peer) ──► Vethc              │
│                                                          │
│                        Target Pod netns                  │
│                        Vethd (Vethc's peer)              │
│                        Vethe                             │
│                        Target Container 0's Veth0  ✅    │
└──────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Step-by-step:

① Host process initiates request to target Pod IP
② Host routing table: Pod CIDR → next hop via Flannel.1
③ Request enters Flannel.1 virtual bridge → exits via Vetha
④ CNI0 bridge's Vethb (Vetha's peer) receives → bridge forwards
⑤ CNI0 bridge's Vethc sends toward target Pod
⑥ Vethd (Vethc's peer in Pod netns) receives → forwards
⑦ Vethe in Pod netns forwards to Container 0's Veth0
⑧ Target Container 0 receives  ✅

Response follows the reverse path.
Enter fullscreen mode Exit fullscreen mode

Scenario 4: Pod → Pod (Different Hosts)

Cross-host Pod communication requires Flannel's overlay network — the flanneld daemon encapsulates packets and routes them through the underlying physical network.

Source Host                          Target Host
┌──────────────────────────┐        ┌──────────────────────────┐
│  Source Pod              │        │  Target Pod              │
│  Container 0             │        │  Container 0             │
│  Veth0 → Vetha           │        │  Vethg ← Veth0           │
│  (src Pod netns)         │        │  (tgt Pod netns)         │
│  Vethb → Vethc (CNI0)    │        │  Vethf ← Vethe (CNI0)    │
│  Vethd → Vethe (CNI0)    │        │  Vethd ← Vethc (CNI0)    │
│  Flannel.1 virtual bridge│        │  Flannel.1 virtual bridge│
│  flanneld intercepts     │        │  flanneld decapsulates   │
│  Vethf (host NIC) ──────────────► Vethg (host NIC)          │
│                          │  UDP   │                          │
│                 physical network  │                          │
└──────────────────────────┘        └──────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Step-by-step:

Source side:
① Container 0 (src) sends via Veth0
② Vetha (peer) receives → src Pod shared netns
③ Vethb sends out of src Pod netns
④ Vethc (CNI0 bridge peer of Vethb) receives
   → CNI0 bridge: destination is on another host
⑤ Vethd on CNI0 bridge sends toward Flannel.1
⑥ Vethe (Flannel.1 peer of Vethd) receives
   → enters Flannel.1 virtual bridge

Flannel overlay:
⑦ flanneld intercepts packet leaving Flannel.1
   → looks up destination IP in routing table
   → destination is on a different host
⑧ flanneld encapsulates packet (VXLAN/UDP)
   → sends via host NIC Vethf to target host

Target side (reverse of source):
⑨ Target host NIC Vethg receives encapsulated packet
   → flanneld decapsulates
   → Flannel.1 → CNI0 bridge → target Pod netns
   → Target Container 0's Veth0 receives  ✅
Enter fullscreen mode Exit fullscreen mode

Flannel's role: flanneld maintains a distributed routing table (backed by etcd) mapping Pod CIDRs to host IPs. When a packet needs to cross hosts, it wraps the original packet in a UDP/VXLAN envelope addressed to the target host's physical IP.


Scenario 5: External App → Cluster Pod

Traffic from outside the cluster must enter through a gateway node, then be routed through Flannel to the target Pod.

External App
     │
     ▼
Gateway Node
┌──────────────────────────────────────────────────────────────┐
│  Gateway service intercepts request                          │
│  Looks up route to target Pod IP                             │
│  Sends via Vetha (gateway NIC) → physical network           │
└──────────────────────────────────────────────────────────────┘
     │ (physical network)
     ▼
Target Pod's Host
┌──────────────────────────────────────────────────────────────┐
│  Vethb (host NIC) receives packet                            │
│  Host routing: → Flannel process                             │
│  Flannel processes packet → Flannel.1 virtual bridge         │
│  Flannel.1 → Vethc → CNI0 bridge                            │
│  CNI0: Vethd → Vethe → target Pod netns                      │
│  Pod netns: Vethf → Vethg → target Container 0's Veth0  ✅   │
└──────────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Step-by-step:

①  External app sends request to cluster Service/NodePort IP
②  Gateway service intercepts the request
③  Gateway looks up route to target Pod's host
④  Request sent via gateway NIC Vetha → physical network
⑤  Target host NIC Vethb receives packet
⑥  Host routing table → Flannel process handles packet
    Flannel → Flannel.1 virtual bridge
⑦  Flannel.1 sends via Vethc
⑧  CNI0 bridge's Vethd (Vethc's peer) receives → bridge forwards
⑨  CNI0 bridge's Vethe sends toward target Pod
⑩  Pod netns Vethf (Vethe's peer) receives → forwards
⑪  Pod netns Vethg forwards to Container 0's Veth0
⑫  Target Container 0 receives  ✅

Response follows the exact reverse path back to external app.
Enter fullscreen mode Exit fullscreen mode

Scenario 6: Cluster Pod → External App

This is simply Scenario 5 in reverse. The packet originates from the container, travels through Pod netns → CNI0 → Flannel.1 → flanneld → host NIC → physical network → gateway → external app.

Target Container 0's Veth0
     → Pod netns (Vethg → Vethf)
     → CNI0 bridge (Vethe → Vethd → Vethc)
     → Flannel.1 (Vethb)
     → flanneld (encapsulate for external routing)
     → Host NIC
     → Physical network
     → Gateway node
     → External app  ✅
Enter fullscreen mode Exit fullscreen mode

The Full Network Stack: Component Roles

Component Layer Role
Veth0 (in container) Container Virtual NIC inside each container
Veth pair (Vethx/Vethy) Pod netns Connect container to Pod's shared network namespace
Pod shared netns Pod Shared network stack — all containers in a Pod share one IP
CNI0 bridge Node Layer 2 virtual switch connecting all Pods on the same node
Flannel.1 Node Virtual bridge for Flannel overlay network entry/exit point
flanneld Node Daemon that encapsulates/decapsulates cross-host packets
Host NIC Node Physical network interface — carries encapsulated overlay traffic
Gateway service Cluster edge Entry point for external traffic into the cluster

Summary: Traffic Path by Scenario

Scenario 1 (same Pod):
Container → Veth0 → Vethx → Pod netns → Vethy → Veth0 → Container

Scenario 2 (same host, diff Pod):
Container → Veth0 → Pod netns → CNI0 bridge → Pod netns → Veth0 → Container

Scenario 3 (host → Pod):
Host process → routing → Flannel.1 → CNI0 bridge → Pod netns → Container

Scenario 4 (diff host):
Container → Pod netns → CNI0 → Flannel.1 → flanneld → host NIC
──[physical network]──►
host NIC → flanneld → Flannel.1 → CNI0 → Pod netns → Container

Scenario 5 (external → Pod):
External → gateway → physical network → host NIC → Flannel → CNI0 → Pod

Scenario 6 (Pod → external):
Pod → CNI0 → Flannel → host NIC → physical network → gateway → external
Enter fullscreen mode Exit fullscreen mode

Understanding these 6 traffic paths gives you a complete mental model of Kubernetes networking — from the veth pair inside a single container all the way to traffic crossing physical datacenter boundaries.


Next in this series: Multi-Cloud & Hybrid Cloud: Kubernetes Federation and Multi-Cluster Use Cases (Part 7)


Follow the series for more deep dives into Kubernetes internals.

Top comments (0)