Kubernetes Networking

10 min read Β· Updated 2026-04-25

Networking is the foundation of distributed Kubernetes systems. Understanding how packets actually flow lets you debug effectively, design resilient architectures, and reason about performance.

This lesson covers pod-to-pod communication, services, ingress, CNI plugins, and network policies β€” the layers that make K8s networking work.

The Networking Model

Kubernetes networking has four core principles:

Each Pod has a unique IP
No port conflicts. No port mapping. App code doesn't need to know about deployment specifics.
Direct Pod-to-Pod communication
Pods talk via IP without NAT. Flat network topology.
Node-to-Pod communication
Nodes can reach pods directly. Required for kubelet, monitoring, kubectl exec.
Consistent IP visibility
A pod sees the same IP that other pods use to reach it. No internal/external IP confusion.

External access is opt-in: pods are private by default; you have to explicitly expose them via Services or Ingress.

The Network Layers

A typical K8s cluster has multiple overlapping networks:

Cluster network
Underlying data center network or cloud VPC. Connects all nodes. Kubernetes doesn't manage it directly.
Node network
Each node has its own IP on the cluster network. Used for node-to-node and node-to-API-server.
Pod network
Pods get IPs from a separate CIDR (e.g., 10.244.0.0/16). Implemented by CNI plugin. Spans across nodes.
Service network
Virtual layer with ClusterIPs from another CIDR (e.g., 10.96.0.0/12). Not physical interfaces β€” managed by kube-proxy via iptables/IPVS.

CNI: The Plugin That Makes Pod Networking Work

Kubernetes itself doesn’t implement pod networking. It delegates to a CNI (Container Network Interface) plugin.

When a pod is created, the CNI plugin:

  1. Assigns an IP from the pod CIDR.
  2. Creates a virtual network interface in the pod’s network namespace.
  3. Sets up routing rules so other pods can reach this one.
  4. Applies network policies (if supported).

Major CNI plugins

Flannel
Simplest. Overlay network with VXLAN. No native NetworkPolicy support. Good for getting started; less common in production.
Calico
BGP-based. Strong NetworkPolicy support. Performance-focused. Used by many enterprise deployments.
Cilium
eBPF-based. Highest performance. Rich features: NetworkPolicy, transparent encryption, service mesh integration, deep observability. Default in many managed K8s distributions.
Cloud-native CNIs
AWS VPC CNI, Azure CNI, GCP CNI. Use cloud-native networking β€” pods get cloud VPC IPs directly. Best performance but tied to the cloud.

Service Networking

Pods are ephemeral. Services provide stable virtual IPs that proxy to the current set of healthy backend pods.

How Services actually work

Pod β†’ ClusterIP (10.96.42.7)
        β”‚
        β–Ό  (kube-proxy iptables/IPVS rules)
        β”‚
   β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”
   β–Ό         β–Ό        β–Ό        β–Ό
 Pod IP1   Pod IP2   Pod IP3   Pod IP4
 (the actual current backend pods)

kube-proxy watches Services and Endpoints, maintaining iptables (or IPVS) rules on every node. When a pod sends a packet to a ClusterIP, the kernel’s netfilter rewrites the destination to a real pod IP β€” random or round-robin among the available backends.

Service types in detail

ClusterIP
Internal-only
Default. Reachable only inside the cluster. DNS name like my-service.namespace.svc.cluster.local. The right choice for service-to-service.
NodePort
Expose via every node
Opens a port on every node (30000-32767). External clients can reach the service via any node's IP at that port. Mostly used for dev/testing.
LoadBalancer
Cloud LB integration
Provisions a cloud load balancer (AWS ELB, GCP forwarding rule). Exposes the service via a stable public IP. Standard for public services.
ExternalName
DNS alias
Maps a service name to an external DNS name (CNAME). No proxying, no IP allocation. Used to give external services in-cluster names.

DNS

CoreDNS runs in every cluster, exposing service names as DNS records:

Pods get the cluster DNS in their /etc/resolv.conf, so a simple curl http://my-service (within namespace) or curl http://my-service.my-namespace (cross-namespace) resolves correctly.

Ingress: HTTP/HTTPS Routing

Services give you Layer 4. Ingress gives you Layer 7.

                    [ Internet ]
                          β”‚
                          β–Ό
                  [ Cloud Load Balancer ]
                          β”‚
                          β–Ό
              [ Ingress Controller Pod ]
              (nginx, Traefik, ALB, etc.)
                          β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β–Ό                 β–Ό                 β–Ό
   [Service A]      [Service B]      [Service C]
   /api/*            /admin/*         /static/*

The Ingress resource is declarative routing config. The Ingress controller is the actual implementation β€” runs as pods, watches Ingress resources, configures itself accordingly.

nginx-ingress
Most popular. Mature, well-documented, broad feature set. nginx under the hood.
Traefik
Modern, dynamic config, native Let's Encrypt integration, easier UX. Strong choice for new clusters.
Cloud-native
AWS ALB Controller, GCP GKE Ingress. Provision cloud load balancers natively.

Gateway API: The Ingress Successor

Gateway API is the modern replacement for Ingress. More expressive, role-oriented:

Gateway
A network entry point. Owned by infrastructure team. Defines listeners, certificates.
HTTPRoute / GRPCRoute / TCPRoute
Route definitions. Owned by app teams. Defines paths/hostnames and target services.
GatewayClass
Defines what implementation provides Gateway resources. Like StorageClass but for networking.

Gateway API will eventually replace Ingress in most clusters. New clusters should use it; existing should migrate.

Network Policies

By default, all pods can talk to all other pods. NetworkPolicies restrict this.

# Allow only pods labeled "app=frontend" to talk to "app=api"
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-from-frontend-only
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend

For production, default-deny is the right baseline:

# Block all ingress to all pods unless explicitly allowed elsewhere
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  podSelector: {}
  policyTypes:
  - Ingress

Service Mesh: Layer 7 Networking as Infrastructure

Service meshes (Istio, Linkerd, Consul Connect) layer additional networking on top of the basic K8s networking:

Universal mTLS
Automatic certificate management between services. Every service-to-service call is mutually authenticated and encrypted.
Traffic management
Weighted routing, canary deploys, fault injection, retries β€” all without app code changes.
Observability
Automatic metrics, tracing, service topology visualization for every service-to-service call.
Authorization
Fine-grained authorization policies between services. "Service A can call Service B's /create endpoint."

We covered this in Service Meshes; in K8s context, it’s typically deployed as sidecar proxies (Envoy for Istio, linkerd2-proxy for Linkerd) injected into every pod.

Multi-Cluster Networking

For larger SaaS platforms running multiple K8s clusters:

Multi-cluster service mesh
Istio multi-cluster, Linkerd multi-cluster. Services in different clusters can talk to each other transparently.
Cluster mesh (Cilium)
Cilium's multi-cluster feature. Pods across clusters share a network plane. Tighter integration than service-mesh-based approaches.
Submariner
Open-source multi-cluster networking. Connects clusters across cloud providers and on-prem.
Cloud-native multi-region
AWS VPC peering / Transit Gateway between regional EKS clusters. Tighter coupling, less operational overhead.

Recap