Kubernetes Networking Model
- Kubernetes does not invent its own networking stack - it maps directly onto the TCP/IP five-layer model.
- Every API object you deploy operates at a specific layer (or bridges layers), with hard constraints on what it can and cannot see.
- Understanding which layer an object works at tells you immediately what it can inspect, what it can route on, and what it cannot do.
Layer Map: K8s Objects vs. OSI
Section titled “Layer Map: K8s Objects vs. OSI”| Layer | Name | Protocol / Concept | Kubernetes Object(s) | What it can see / do |
|---|---|---|---|---|
| 1 | Physical | Cables, NICs, radio | Node hardware, CNI plugin (physical wiring) | Raw bit transmission - no K8s API objects here |
| 2 | Data Link | Ethernet, MAC addresses | CNI plugin (Calico, Cilium, Flannel) - ARP, VXLAN | MAC-level forwarding; MetalLB L2 mode announces Service IPs via ARP at this layer |
| 3 | Network | IP, ICMP, routing | Pod (each gets a routable IP), CNI routing tables | IP-to-IP routing; Pod network model guarantees NAT-less, flat L3 addressability |
| 4 | Transport | TCP, UDP, SCTP, ports | Service (ClusterIP, NodePort, LoadBalancer), kube-proxy, EndpointSlices | Port-based load balancing and session affinity; cannot inspect HTTP headers or paths |
| 7 | Application | HTTP, gRPC, TLS, DNS | Ingress, Gateway API, ExternalName (CNAME) | Host/path routing, TLS termination, header manipulation, redirects |
Per-Object Layer Breakdown
Section titled “Per-Object Layer Breakdown”Pod - Layer 3
Section titled “Pod - Layer 3”- Each Pod gets a unique routable IP on the cluster’s flat L3 network.
- Pods communicate with each other at Layer 3 - pure IP routing, no NAT.
- The CNI plugin (Calico, Cilium, Flannel) implements the actual L3 forwarding rules.
- Cannot discriminate traffic by port or application content on its own - that requires a Service or NetworkPolicy.
Service (ClusterIP / NodePort / LoadBalancer) - Layer 4
Section titled “Service (ClusterIP / NodePort / LoadBalancer) - Layer 4”- Services operate purely at L4 (TCP/UDP) via
iptablesor IPVS rules managed bykube-proxy. - They route based on IP + port only - no HTTP headers, no hostnames, no paths.
sessionAffinity: ClientIPis L4 stickiness (source IP), not cookie-based (L7).LoadBalancerextends to L4 at the cloud provider boundary - the cloud LB (AWS NLB, GCP LB) is typically also L4 unless you configure an ALB/HTTP LB explicitly.
NetworkPolicy - Layer 3 / Layer 4
Section titled “NetworkPolicy - Layer 3 / Layer 4”- NetworkPolicies are a L3/L4 firewall - they filter on:
- L3: Pod IP / CIDR / namespace selector
- L4: port + protocol (TCP/UDP)
- They cannot filter on HTTP methods, paths, or headers.
- Enforcement is done by the CNI plugin (not kube-proxy) - NetworkPolicy has no effect without a CNI that supports it (Calico, Cilium do; Flannel alone does not).
Ingress - Layer 7
Section titled “Ingress - Layer 7”- Ingress controllers (nginx, Traefik, HAProxy) operate at L7 (HTTP/HTTPS).
- They can route on: hostname (
api.example.com), path (/users,/orders), HTTP headers. - Handle TLS termination - decrypt HTTPS at the controller, forward plain HTTP to backend Services.
- Sit in front of ClusterIP Services - the traffic path is:
Internet -> Ingress (L7) -> ClusterIP Service (L4) -> Pod (L3).
Gateway API - Layer 7 (+ L4 via TCPRoute)
Section titled “Gateway API - Layer 7 (+ L4 via TCPRoute)”- The successor to Ingress, with more expressive L7 routing (header manipulation, traffic weights, cross-namespace references).
- Also supports L4 routing via
TCPRoute/UDPRouteresources for non-HTTP protocols. - Splits responsibility across roles:
GatewayClass(infra),Gateway(L4 listener config),HTTPRoute(L7 rules).
ExternalName Service - Layer 7 (DNS / CNAME)
Section titled “ExternalName Service - Layer 7 (DNS / CNAME)”- ExternalName is purely a DNS trick - it emits a CNAME record at L7 (application-layer DNS).
- No L4 proxy, no ClusterIP, no kube-proxy involvement.
- The client resolves the CNAME and connects directly to the external host at L3/L4.
CoreDNS - Layer 7
Section titled “CoreDNS - Layer 7”- The cluster DNS server - operates at L7 (Application layer, DNS protocol).
- Automatically registers A/AAAA records for every Service and SRV records for named ports.
- Pods query CoreDNS via a
/etc/resolv.confsearch path injected by the Kubelet.
Traffic Path by Layer (End-to-End)
Section titled “Traffic Path by Layer (End-to-End)”flowchart TD
Client(["fa:fa-globe <b>Internet Client</b>"])
subgraph Cloud [" <b>Cloud Infrastructure</b> "]
LB["fa:fa-cloud <b>Cloud Load Balancer</b> [L4: TCP/UDP]<br/>AWS NLB / GCP LB / Azure LB"]
end
subgraph Cluster [" <b>Kubernetes Cluster</b> "]
direction TB
Ingress["fa:fa-route <b>Ingress Controller Pod</b> [L7: HTTP/HTTPS]<br/>TLS termination • Host & path routing • Header inspection"]
Svc["fa:fa-network-wired <b>Service / kube-proxy</b> [L4: TCP/UDP]<br/>DNAT to Pod IP:port via iptables / IPVS / eBPF"]
App["fa:fa-cube <b>Application Pod</b> [L7: Application]<br/>App runtime processes HTTP request"]
Ingress -->|"L4: Proxies to ClusterIP Service"| Svc
Svc -->|"L3: Routed to Pod IP via CNI"| App
end
Client -->|"L3/L4: TCP SYN to cloud LB public IP"| LB
LB -->|"L4: Forwards to NodePort (30000–32767)"| Ingress
Why the Layer Matters: Decision Guide
Section titled “Why the Layer Matters: Decision Guide”| You need to… | Use this object | Layer |
|---|---|---|
| Expose a backend only to other Pods | ClusterIP | L4 |
| Expose on a node port for bare-metal external access | NodePort | L4 |
| Expose with a cloud-managed public IP | LoadBalancer | L4 |
Route host.com/path-a vs host.com/path-b | Ingress / Gateway API | L7 |
| Terminate TLS at the cluster boundary | Ingress / Gateway API | L7 |
| Block Pod-to-Pod traffic by namespace or IP range | NetworkPolicy | L3/L4 |
| Give an external hostname a cluster-internal alias | ExternalName | L7 (DNS) |
| Route directly to individual Pod IPs (StatefulSet) | Headless Service | L3 |
| Expose a non-HTTP TCP/UDP service via Gateway | TCPRoute / UDPRoute | L4 |