Skip to content
Back to blog

Kubernetes Request Flow: How Traffic Reaches Your Pod

July 6, 20265 min read

You deployed your app to Kubernetes and opened the URL — but what actually happens between the browser and your container? A request crosses DNS, a cloud load balancer, an Ingress controller, a Service, EndpointSlices, kube-proxy, and finally lands in a Pod where your application code runs.

Understanding this path is essential for debugging 502 errors, tuning health checks, and explaining system design in interviews. This article walks through all ten hops — from the user typing a URL to the response traveling back — with the networking objects that make each step possible.

UserDNSLBIngressServicePodContainerResponse travels back along the same path
Request path: User → DNS → Load Balancer → Ingress → Service → Pod → Container

User, DNS, and Load Balancer

The journey starts when a user opens a URL like `https://app.example.com`. The browser does not know your cluster — it asks public DNS to resolve the hostname. DNS returns the external IP of your cloud load balancer (AWS NLB/ALB, GCP Load Balancer, Azure LB) or the IP exposed by your Ingress controller.

The load balancer sits at the cluster edge. It terminates TLS (or passes it through), accepts TCP/HTTP traffic from the internet, and forwards it into the cluster network. Without this layer, Pod IPs would be unreachable from outside — they live on private cluster networks that are not routable on the public internet.

1Userhttps://app.example.com2DNSResolves to LB IP3Load BalancerForwards into clusterPublic DNS returns the external IP of your cloud load balancer or ingress endpoint
Steps 1–3: user opens a URL, DNS resolves, load balancer accepts traffic

Quick reference

  • Step 1: user sends HTTP request to a public hostname.
  • Step 2: DNS resolves domain → external load balancer IP.
  • Step 3: load balancer receives traffic and forwards into the cluster.
  • Use health checks on the LB so unhealthy nodes are removed.
  • TLS can terminate at LB, Ingress, or both (double encryption).
  • Cloud LB type matters: L4 (TCP) vs L7 (HTTP routing).

Remember this

DNS points users at the load balancer — the front door into your Kubernetes cluster.

Ingress, Gateway, and Service

Inside the cluster, Ingress (or the newer Gateway API) performs HTTP/HTTPS routing. It reads rules like "host = app.example.com, path = /api → backend-service" and forwards the request to the correct internal Service. Ingress controllers (NGINX, Traefik, AWS ALB Ingress Controller) watch Ingress resources and configure themselves dynamically.

A Service gives your app a stable virtual IP and DNS name (`backend-service.production.svc.cluster.local`) even though Pod IPs change constantly. Services do not run code — they are a routing abstraction. ClusterIP Services are internal-only; LoadBalancer and NodePort types expose Services externally (often via cloud LB integration).

Ingress\n/api → backendService\nstable VIP/DNSEndpointSlice\nready Pod IPsIngress handles HTTP/HTTPS routing · Service abstracts away changing Pod addressesGateway APIModern alternativeAdvanced L4/L7 routingReplaces Ingress over time
Steps 4–5: Ingress routes by host/path; Service provides a stable virtual endpoint

Quick reference

  • Step 4: Ingress/Gateway routes by hostname and URL path.
  • Step 5: Service provides stable endpoint — hides Pod churn.
  • Ingress: mature, HTTP-focused — most clusters use it today.
  • Gateway API: successor with richer L4/L7 routing models.
  • ClusterIP: default internal Service type.
  • Internal DNS: service-name.namespace.svc.cluster.local.

Remember this

Ingress picks the right Service; the Service is the stable name your app is known by inside the cluster.

EndpointSlices and kube-proxy

EndpointSlices (replacing the older Endpoints object) track which Pod IPs and ports are ready to receive traffic for a Service. When a Pod passes its readiness probe, it appears in the EndpointSlice; when it crashes or fails health checks, it is removed. This is how Kubernetes knows which backends are actually healthy.

kube-proxy runs on every node and programs network rules (iptables, IPVS, or eBPF) so traffic destined for a Service VIP is forwarded to a healthy Pod IP. The selection is typically round-robin or random across ready endpoints. If all Pods are unhealthy, the Service has no endpoints and clients see connection failures or 503 responses.

EndpointSlicekube-proxyPod APod BPod Ckube-proxy on each node applies Service routing rules to cluster network traffic
Steps 6–8: EndpointSlices track healthy Pods; kube-proxy forwards to a selected Pod

Quick reference

  • Step 6: EndpointSlice lists ready Pod IP:port pairs.
  • Step 7: kube-proxy forwards Service traffic to a Pod.
  • Readiness probes control EndpointSlice membership.
  • Liveness probes restart crashed containers.
  • No ready endpoints → 503 / connection refused.
  • kube-proxy modes: iptables (default), IPVS, or eBPF (Cilium).

Remember this

EndpointSlices tell kube-proxy which Pods are healthy; kube-proxy does the actual packet forwarding.

Pod, Container, and Response

The request reaches a Pod — the smallest deployable unit in Kubernetes, usually one or more containers sharing a network namespace. Traffic arrives on the Pod IP at the container port defined in your Deployment spec (e.g. port 8080).

The container runs your application process. It handles the HTTP request — parse headers, query a database, call another Service, build a response. When done, the response travels back along the same path in reverse: container → Pod network → kube-proxy → Service → Ingress → load balancer → internet → user browser.

PodContainerApp logicResponseContainer runs your app process — query DB, call APIs, return JSON/HTML
Steps 9–10: container handles the request; response returns along the same path

Quick reference

  • Step 8: request arrives at selected Pod via cluster network.
  • Step 9: application container processes the request.
  • Step 10: response returns User ← LB ← Ingress ← Service ← Pod.
  • Pod IP is ephemeral — never hardcode it in clients.
  • Sidecar containers in the same Pod share localhost networking.
  • NetworkPolicies can restrict which Pods may talk to each other.

Remember this

Pods are ephemeral; Services and Ingress give the outside world a stable way to reach them.

Important Notes for Production

Several details catch teams off guard in real clusters. Services hide changing Pod IPs — always call other workloads by Service DNS, never by Pod IP. Ingress handles external HTTP routing; internal service-to-service calls use ClusterIP DNS directly, skipping Ingress entirely.

The internal DNS pattern is `service-name.namespace.svc.cluster.local` — for example `backend-service.production.svc.cluster.local`. Short names like `backend-service` work within the same namespace. Gateway API is gradually replacing Ingress for advanced routing (header-based rules, traffic splitting, TLS management), but the conceptual flow remains the same.

When debugging, trace the path: can DNS resolve? Does the LB health check pass? Does Ingress have the right host rule? Does the Service have endpoints (`kubectl get endpointslices`)? Is the Pod ready?

Quick reference

  • Never call Pod IPs directly — use Service DNS.
  • External traffic: User → LB → Ingress → Service → Pod.
  • Internal traffic: Pod → Service DNS → Pod (skips Ingress).
  • kubectl get endpointslices -n <ns> — see ready backends.
  • 502 often means Ingress cannot reach Service or no endpoints.
  • Gateway API: modern replacement for Ingress routing.

Remember this

Debug the chain top-down: DNS → LB → Ingress rules → Service endpoints → Pod readiness.

Key takeaway

Share:

A Kubernetes request is not magic — it is a chain of well-defined networking layers. DNS finds the load balancer, Ingress routes HTTP to the right Service, EndpointSlices track healthy Pods, kube-proxy forwards packets, and your container finally handles the request. Learn this path once and you can diagnose production outages in minutes instead of hours. The response simply unwinds the same chain on the way back to the user.

Related Articles

Microservices are not a single tool — they are an ecosystem. You need containers to package services, databases to store

Read

Docker and Kubernetes show up in the same sentence constantly, but they operate at different layers. Docker is a **conta

Read

Containers are ephemeral by design — when you remove one, its filesystem disappears with it. That is fine for stateless

Read

Explore this topic

Keep learning

Follow a structured path or browse all courses to go deeper.