Begin with one Pod
Imagine a web application that calls an API. Before connecting the two, look at where one application runs.
Kubernetes schedules containers in a Pod. A Pod can contain a single container or a few containers that need to run together. In an ordinary Pod, those containers share one network namespace—the Linux view of interfaces, addresses, routes, and ports. Pod networking ↗
Pod IP · 10.244.1.10Shared network namespace
listens on :8080localhost:9090request / response via lolistens on :909010.244.1.10Pod network interfaceKeep this idea: containers in one Pod share localhost. They must coordinate ports because they cannot independently listen on the same address and port. A different Pod has its own localhost.
Reach another Pod
Now put the API in its own Pod. The web application must use the API Pod’s address; calling localhost would still reach only its own Pod.
Cluster network
Pod IP · 10.244.1.10Shared network namespace
listens on :808010.244.1.10Pod network interfaceAPI destination10.244.2.10:8080Node-to-Node networkRequest → API · response returns to webPod IP · 10.244.2.10Shared network namespace
listens on :808010.244.2.10Pod network interfaceA Node is a machine running Pods. The cluster’s network implementation connects those Pods across Nodes. CNI is the interface through which the runtime invokes network plugins during Pod setup. You can understand the connection before learning which Linux interfaces implement it.
Keep this idea: different Pods communicate through Pod addresses. The app must be listening, and the network and security rules must permit the connection.
Inside the Node: follow the interfaces
This Linux bridge example expands the Pod attachments and Node forwarding paths above. Follow one path at a time: inside a Pod, between local Pods, then across Nodes. Other network implementations use different attachments and forwarding.
Follow a packet from Pod eth0 to the network
The Pod and Node boundaries are the same ones used above. This time, the middle is expanded to show one bridge-based CNI datapath.
Node IP · 192.168.1.1010.244.1.1/2410.244.2.0/24 via Node B192.168.1.10Node A ⇄ Node BNode IP · 192.168.1.20192.168.1.20destination 10.244.2.10Pod IP · 10.244.2.10Shared network namespace
listens on :808010.244.2.10Pod network interfaceWhat changes as the destination moves farther away?
localhost:9090The kernel finds the Helper socket in the shared Pod namespace. The packet never reaches eth0.
eth0 → veth-web → cni0 → veth-api → eth0The bridge switches the Pod packet locally. Host routing and the Node NIC are not needed.
eth0 → veth → route → ens5 ⇄ ens5 → PodRouting or an overlay carries the traffic between Nodes. An overlay adds an outer Node-to-Node packet.
These steps create the path; they do not repeat for every packet
- 1Kubeletrequests a Pod sandbox through CRI
- 2Runtimecreates the sandbox network namespace
- 3CNI ADDattaches networking; IPAM may allocate an address
- 4Data planeinstalls interfaces, routes, and policy state
Where this example stops: the bridge, interface names, and address ranges are illustrative. Other implementations can route directly, attach cloud interfaces, use eBPF, or encapsulate packets. Kubernetes specifies the connectivity outcome rather than this exact Linux layout.
How the Pod gets connected
All regular containers in a Pod share the Pod sandbox’s network namespace, addresses, interfaces, routes, and port space. They communicate over localhost; two containers cannot independently bind the same address and port. The sandbox may be represented by an infrastructure container, but “the pause container owns networking” is an implementation shortcut, not the Kubernetes contract. Pod networking ↗
- Step 1 · Kubelet
Request the Pod sandbox
CRI RunPodSandboxKubelet asks the node runtime to prepare the Pod sandbox.
- Step 2 · Container runtime
Prepare network isolation
Network namespaceIn this ordinary Linux Pod example, the namespace exists before network attachment.
- Step 3 · CNI plugins
Attach and configure networking
CNI ADD + optional IPAM delegationThe runtime supplies the namespace reference and configuration. Plugins configure networking and may delegate address allocation.
- Step 4 · Container runtime
Receive the plugin result
Interfaces, IPs, routes, DNSThe runtime receives the CNI result. Exact interfaces and forwarding mechanisms belong to the plugin implementation.
- Step 5 · Pod sandbox
Share the configured network
Pod IP + shared port spaceContainers in this Pod use the sandbox network. This setup is not repeated for each packet.
Read top to bottom. Dashed arrows show the conceptual sequence, not network calls. Select a numbered node to inspect a step. Scroll sideways on narrow screens to see every participant.
CNI is an execution protocol between a runtime and plugin binaries. It defines operations such as ADD, DEL, CHECK, GC, STATUS, and VERSION; it does not mandate a bridge, an overlay, a particular IPAM database, or NetworkPolicy enforcement. Plugins can be chained, and an IPAM plugin can be delegated address allocation. CNI specification ↗
When a Pod is deleted, the runtime invokes cleanup. A leaked IP allocation, stale interface, or failed plugin daemon can therefore break later Pod creation even when the Kubernetes objects look valid.
Compare Node, Pod, and Service addressesOptional detail
Nodes, Pods, and Services commonly draw addresses from separate, non-overlapping ranges. Different components allocate and route each range, so available addresses in one pool say nothing about capacity in another. A dual-stack cluster repeats these responsibilities for IPv4 and IPv6, and every participating component must support the configured families. Cluster address ranges ↗
| Address | Usually allocated by | What it identifies | Important consequence |
|---|---|---|---|
| Node IP | kubelet or cloud integration | A machine participating in the cluster | May carry encapsulated pod traffic or receive NodePort traffic. |
| Pod IP | Pod network implementation / IPAM | One Pod sandbox | Normally changes when a replacement Pod is created. |
| ClusterIP | Kubernetes control plane | A virtual Service frontend | It is not a backend and need not be assigned to an interface. |
| External address | Cloud, load-balancer, or gateway implementation | An entry point outside the pod network | Its path and source-IP behavior are provider-specific. |
| DNS name | Cluster DNS and upstream DNS | A discoverable name, not a packet hop | The answer may be a Service VIP, Pod addresses, or an external alias. |
containerPort documents an application port but does not publish it. hostPort binds a Pod port on a Node and creates scheduling/port constraints. hostNetwork: true places the Pod in the Node network namespace instead of the ordinary pod network. These are exceptions, not the default path.
Give the API a stable address
Pods can be replaced, and replacement Pods can receive different addresses. A Service gives the web application a stable destination while the API Pods behind it change.
For the ordinary internal Service below, the web app first asks cluster DNS for the name api. DNS returns the Service’s virtual IP, called a ClusterIP. When the app connects, the Service’s forwarding implementation selects an eligible backend Pod.
Cluster network
Pod IP · 10.244.1.10Shared network namespace
listens on :808010.244.1.10Pod network interface10.96.0.20:80Virtual frontend10.244.2.10:8080Node-to-Node networkForwarding maps the Service port to the backend port.Pod IP · 10.244.2.10Shared network namespace
listens on :808010.244.2.10Pod network interfaceThe Service’s port: 80 is what callers use; targetPort: 8080 is where the API listens. EndpointSlices are the backend records the Service implementation consults. Services ↗
Keep this idea: DNS finds the address; Service forwarding gets the connection to a backend. A successful name lookup does not prove that the API can answer.
The controller publishes Pods that match the selector
This Service selects app=api. Change each Pod's labels and readiness to see what the EndpointSlice controller publishes and which addresses a typical Service data plane can choose for a new connection.
selector: app=apiport 80 → targetPort 8080No matching Pods: the slice contains no endpoints.
No ready endpoints remain.
10.244.1.12:8080Published · ready=true10.244.2.18:8080Published · ready=true10.244.3.24:8080Not selected2 published · 2 eligibleThe data plane can choose either ready endpoint for a new connection.
This is a selector-based Service with one illustrative IPv4 slice and explicit readiness values. Real Services can span multiple EndpointSlices, address families, ports, and topology domains. EndpointSlice consumers must combine every slice labeled for the Service. Existing connections can outlive a readiness change. EndpointSlice semantics ↗
Inspect backend selection and compare all Service formsOptional detail
A Service separates a stable frontend from a changing backend set. For a selector-based Service, the control plane finds matching Pods and maintains EndpointSlices. Each slice groups endpoints with compatible address family, protocol, port, and Service identity. Readiness, serving, and terminating conditions help consumers decide whether an endpoint should receive new traffic. Services ↗ EndpointSlices ↗
The legacy Endpoints API is deprecated from Kubernetes v1.33; EndpointSlice is the scalable source for modern consumers. The default slice target is up to 100 endpoints, but slices are not continually repacked just to be full because every update must propagate to consumers across the cluster.
Endpoint removal is also a convergence process rather than one instantaneous switch. The timeline below shows why readiness, published endpoint state, proxy state, and existing connections can briefly disagree while a Pod terminates.
- 01Readyready=true
serving=true → - 02Termination beginsdeletion timestamp
readiness changes → - 03Drainingterminating=true
ready=false
serving may remain true → - 04RemovedNo longer published
connections finish or close
A graceful shutdown gives readiness changes time to reach EndpointSlices and traffic handlers before the process exits. The application, controller, proxy, and load balancer still reconcile on their own schedules.
| Form | Frontend | Typical use | Caveat |
|---|---|---|---|
| ClusterIP | Cluster-internal virtual IP | Stable in-cluster access | Requires a working Service data plane. |
| Headless | No ClusterIP | Direct DNS discovery of endpoints | Clients see backend churn and implement their own selection behavior. |
| NodePort | Node address plus allocated port | Simple external or load-balancer target | Firewall, source IP, and cross-node behavior matter. |
| LoadBalancer | Implementation-provisioned external address | Provider-integrated external access | Kubernetes declares intent; a controller must provide the load balancer. |
| ExternalName | DNS CNAME | Alias to an external DNS name | No proxying or endpoint health management is created. |
Under the hood: kube-proxy, forwarding rules, and existing connectionsOptional detail
kube-proxy is Kubernetes’ default Service proxy, but a pod network implementation can replace it. On Linux, kube-proxy can program iptables or nftables; IPVS mode is deprecated from Kubernetes v1.35 because it cannot correctly represent every Service edge case. Windows uses a different kernel data plane. Virtual IPs and proxies ↗
The word “proxy” is easy to misread: kube-proxy usually programs kernel forwarding rules rather than accepting every connection in a user-space process. A ClusterIP is similarly virtual—the Service API defines the frontend, while the chosen implementation decides how packets addressed to it are intercepted and redirected.
| Mode | Mechanism | Operational implication |
|---|---|---|
| iptables | Netfilter rules and destination NAT | Widely deployed; large rule sets can increase synchronization work. |
| nftables | nftables rules and destination NAT | Newer Linux mode with different NodePort and firewall defaults; verify kernel and Kubernetes support. |
| IPVS | IPVS plus iptables integration | Deprecated from v1.35; plan migrations instead of choosing it for new clusters. |
| Replacement data plane | Implementation-specific, often eBPF or provider integrated | Do not expect kube-proxy processes or KUBE-* rules when it has been replaced. |
Removing a Pod from EndpointSlices stops it from being selected for new traffic after consumers reconcile the update. Existing application connections and connection-tracking entries have their own lifetimes, so they can continue using that Pod after readiness changes.
Inspect DNS names, resolver configuration, and discovery failuresOptional detail
Cluster DNS commonly runs CoreDNS behind a Service historically named kube-dns. With the usual ClusterFirst policy, kubelet writes a cluster DNS nameserver and search suffixes into the Pod’s resolver configuration. A query such as api can expand to api.<namespace>.svc.<cluster-domain>; cross-namespace callers normally use api.<namespace> or the full name. The cluster domain is configurable and is not always cluster.local. DNS for Services and Pods ↗
- 01Application asks resolverSearch paths and ndots influence which names are queried.
- 02Cluster DNS answersA normal Service returns its ClusterIP; a headless Service can return endpoint addresses.
- 03Application opens a connectionThe returned address becomes the packet destination.
- 04Network delivers trafficService proxying or direct pod routing handles the result.
A correct DNS answer proves that the client discovered an address. The following connection can still time out because the Service has no ready endpoints, forwarding state is stale, policy blocks the packet, or the application is not listening. Likewise, a successful direct Pod-IP test has bypassed both DNS and the Service frontend.
ClusterFirstWithHostNet is the usual cluster-DNS choice for Pods using hostNetwork. dnsPolicy: None requires explicit dnsConfig. Search expansion can also amplify DNS traffic, so inspect the actual query name and the Pod’s /etc/resolv.conf rather than assuming what the application asked.
Choose how callers reach it
For our web app calling its API inside the cluster, start with ClusterIP. When callers are outside the cluster, choose the entry behavior they need.
| What you need | Start here | Why |
|---|---|---|
| Web app → API inside the cluster | ClusterIP Service | Stable internal access to changing Pods. |
| External access to one TCP/UDP service | LoadBalancer Service | A supported implementation provisions a reachable load balancer. |
| HTTP/HTTPS host or path routing | Gateway API or Ingress | A controller configures entry routing and, commonly, TLS. |
A LoadBalancer Service needs a supporting controller or provider. Gateway and Ingress resources also need an implementation. Creating their configuration alone does not make the application reachable.
https://app.example.comCluster network
Route backend: web ServicePod IP · 10.244.1.10Shared network namespace
listens on :808010.244.1.10Pod network interfaceAPI destination10.244.2.10:8080Node-to-Node networkRequest → API · response returns to webPod IP · 10.244.2.10Shared network namespace
listens on :808010.244.2.10Pod network interfaceThis example shows the logical path; the gateway implementation determines whether it connects through the Service IP or directly to backend Pods.
Service types and where to use them
Choose the frontend by who must reach it
A Service gives a changing backend set a stable way to be found. The Service type changes the frontend and exposure mechanism; Ingress and Gateway API add protocol-aware routing rather than becoming new Service types.
ClusterIPdefaultUse for: stable internal application access.
The Service data plane chooses an eligible endpoint. The VIP is not an application process.HeadlessclusterIP: NoneUse for: peer discovery and clients that need individual endpoint addresses.
No virtual-IP load balancing. Clients must handle churn, selection, and cached answers.NodePortnode IP + portUse for: simple exposure or an implementation’s load-balancer target.
Node reachability, firewall rules, traffic policy, and source translation all matter.LoadBalancercontroller requiredUse for: one externally reachable TCP or UDP service.
The implementation decides whether it targets Nodes, NodePorts, or Pods directly.ExternalNameDNS CNAMEUse for: a Kubernetes-local alias to a DNS name you manage elsewhere.
No proxy, health check, ClusterIP, or EndpointSlice backend is created.Add a routing API when many routes share entry infrastructure
HTTPS :443status → programmed data plane→ eligible endpointPrefer Gateway API for new, multi-team routing designs. Ingress remains common and stable but is frozen. A resource object does not carry traffic by itself; an implementation must accept it and program a reachable data plane.
Explore Gateway and Ingress configurationOptional detail
External traffic needs infrastructure that can receive packets and an API/controller combination that maps them toward Services or endpoints. A LoadBalancer Service handles a relatively direct exposure model. Ingress and Gateway API add protocol-aware routing, usually for HTTP and HTTPS.
Ingress is stable but frozen; the Kubernetes project recommends Gateway API for new capabilities. Creating an Ingress, Gateway, or Route object alone does not create a working data path—an implementation controller must accept it and report useful status. Gateway API separates GatewayClass, Gateway, and route resources such as HTTPRoute, allowing infrastructure owners, cluster operators, and application teams to control different layers. Ingress ↗ Gateway API ↗
- 01GatewayClassNames the controller and implementation class.
- 02Gateway + listenerRequests an address, port, protocol, TLS, and attachment policy.
- 03HTTPRouteMatches host, path, headers, or other request attributes.
- 04Service backendTargets a Service and ultimately eligible endpoints.
Where TLS terminates, whether traffic reaches NodePorts or Pod addresses directly, which health checks run, and whether the original client address survives are implementation decisions. Read controller status and documentation instead of treating the conceptual arrows as guaranteed hops.
Explore local endpoints and client source addressesOptional detail
Service routing can express strict constraints and softer preferences. internalTrafficPolicy: Local restricts internal Service traffic to node-local endpoints; on a node with none, the Service behaves as if it has no endpoints there. externalTrafficPolicy: Local can preserve client source addresses and avoid an extra node hop, but may reduce load distribution and requires entry traffic to land on nodes with local endpoints. Internal traffic policy ↗ Source IP ↗
trafficDistribution expresses preferences such as same-zone or same-node routing in supported versions; it is not the same as the hard Local constraint. EndpointSlice topology and hints can guide the proxy, but implementations may fall back to cluster-wide endpoints when safeguards are not satisfied.
Always test the source address as observed by the application. Load balancers, node forwarding, proxies, and externalTrafficPolicy can change it, and NetworkPolicy ipBlock behavior can be affected by where address translation occurs.
A healthy remote Pod cannot rescue a strict Local route
The client is on Node A. Change endpoint readiness and the Service’s internal traffic policy, then inspect which destinations remain eligible for a new connection.
Local backend
10.244.1.12:8080✓ EligibleReady and included by Cluster policy.Remote backend
10.244.3.12:8080✓ EligibleReady and included by Cluster policy.2 eligible endpointsEither backend can receive a new connection; this diagram does not prescribe selection order.
This shows the state after reconciliation for ordinary, non-terminating endpoints, with publishNotReadyAddresses: false. Actual readiness propagation is asynchronous; existing connections have separate lifetimes. Solid arrows represent a possible connection, not simultaneous delivery to all backends. Internal traffic policy ↗
Decide who may connect
Our web app needs to call the API. Other workloads might not. NetworkPolicy lets you describe allowed Pod traffic when the installed network implementation supports enforcement.
Think about a connection from both ends: permission to leave the web Pod (egress) and permission to enter the API Pod (ingress).
Cluster network
Pod IP · 10.244.1.10Shared network namespace
listens on :808010.244.1.10Pod network interfaceAPI destination10.244.2.10:8080Both permissions must allow the connectionRequest → API · response returns to webPod IP · 10.244.2.10Shared network namespace
listens on :808010.244.2.10Pod network interfacePods begin non-isolated in each direction. Selecting them with policies can restrict that direction; applicable allow rules add together. When introducing default-deny egress, allow the DNS traffic and other dependencies your app requires. NetworkPolicy ↗
Keep this idea: a route makes a destination reachable; policy decides whether the connection is permitted. Application identity and authorization add another layer.
One connection needs permission at both ends
Test a new TCP connection from frontend to api:8080 using a known Pod IP. Toggle isolation and matching allow rules; a second rule can restore access without removing the isolation policy.
Egress gate
Ingress gate
BLOCKED by NetworkPolicyThe destination ingress gate blocks this connection.
With no isolation, that direction is unrestricted by NetworkPolicy. Matching allow policies themselves select and isolate a direction; the controls keep that relationship consistent. This model excludes host-network exceptions, other filtering, DNS, and application health. “Permitted” describes NetworkPolicy only. Kubernetes policy semantics ↗
Put each control at the boundary it can actually see
Reachability, workload permission, and application identity are different decisions. A packet can pass NetworkPolicy and still fail TLS or authorization; an authenticated request can never arrive if routing or egress policy blocks it first.
203.0.113.5reachable IP + allowed portTLS · host/path · auth integrationsource + protocol + portidentity + authorizationfrontend → TCP 8080If this direction is isolated, some applicable policy must allow the connection.
from frontend → TCP 8080If this direction is isolated, destination policies must independently allow it.
Use namespace and Pod selectors for workload relationships. Use ipBlock mainly for external CIDRs, and verify how the deployed data plane orders NAT and policy.
Use for hostname, path, certificate, rate-limit, and authentication decisions when the implementation supports them.
mTLS or signed tokens can authenticate a workload across changing addresses. Authorization remains an application or policy-layer decision.
Security groups, host firewalls, and routing constrain Node or interface reachability. Their scope is provider- and datapath-specific.
Practical baseline: confirm policy enforcement exists, default-deny ingress and egress per namespace where appropriate, explicitly allow cluster DNS and required dependencies, restrict external entry, encrypt sensitive paths, and test the effective flow from a representative Pod.
Try policy examples and inspect the security controlsOptional detail
By default, Pods are non-isolated for ingress and egress. A NetworkPolicy begins isolation only for the selected Pods and directions, and allowed traffic is the union of every applicable policy—policies are additive, not processed in order. For Pod A to initiate a connection to Pod B, A’s egress policy and B’s ingress policy must both allow it when each side is isolated. Reply traffic for an allowed connection is implicitly allowed. NetworkPolicy ↗
The API does nothing unless the installed network implementation enforces NetworkPolicy. The standard model is primarily Layer 3/4 and defines TCP, UDP, and optionally SCTP behavior; ICMP and other protocols can vary. It does not replace application authentication or authorization.
No selecting policy means no isolation
Creating one policy for a different workload does not make the whole namespace default-deny.
Ingress and egress are independent
A source can allow egress while the destination still rejects ingress, or the reverse.
Another policy cannot subtract an allow
The allowed set is the union of applicable rules. There is no first-match order.
Default-deny egress also blocks DNS
Add the DNS traffic your workloads require, using addresses and ports that match the actual cluster DNS path.
Put the four paths together
You have now met the four networking paths: containers within a Pod, Pod to Pod, Pod to Service, and external callers reaching workloads. Open any path below to follow the detailed sequence.
Follow the components each connection needs
Open a path, then step through it or select any numbered node. Each trace is a conceptual sequence; actual forwarding varies by implementation.
01Inside one PodShared network namespace
- Step 1 · Container A
Open a local connection
127.0.0.1:8080The client uses the loopback address shared by containers in this Pod.
- Step 2 · Pod namespace
Deliver over loopback
Shared addresses and portsThe kernel finds the listening socket in the same network namespace. This does not test CNI forwarding.
- Step 3 · Container B
Accept the connection
Application port 8080The application must listen on the matching address and port. No Service is involved.
Read top to bottom. Dashed arrows show the conceptual sequence, not network calls. Select a numbered node to inspect a step. Scroll sideways on narrow screens to see every participant.
The containers share IP addresses and ports. They must coordinate port usage.
02Pod → PodDirect pod addresses
- Step 1 · Source Pod
Address the backend directly
10.244.3.12:8080This cross-node example starts with a known Pod IP. Enforced source egress and destination ingress policy still apply.
- Step 2 · Source node
Forward toward the remote Pod
Implementation-specific routeThe installed data plane makes the Pod destination reachable. Kubernetes does not require a bridge or overlay.
- Step 3 · Destination node
Deliver to the Pod network
Routing or decapsulationAn overlay removes its outer envelope; native routing does not need that envelope. Actual attachment and enforcement points vary.
- Step 4 · Backend Pod
Reach the application socket
10.244.3.12:8080Success here does not establish that Service proxying or DNS works.
Read top to bottom. Dashed arrows show the conceptual sequence, not network calls. Select a numbered node to inspect a step. Scroll sideways on narrow screens to see every participant.
Same-node and cross-node forwarding are implementation details: routing, switching, encapsulation, cloud interfaces, or eBPF may be involved.
03Pod → ServiceStable frontend, changing backends
- Step 1 · Client Pod
Resolve the Service name
api.team.svc.cluster.localThis example uses cluster.local; the real cluster domain is configurable. The DNS exchange is separate from application traffic.
- Step 2 · Cluster DNS
Return the virtual address
10.96.0.20For this normal Service, DNS answers with the ClusterIP, not a chosen backend. Headless Services behave differently.
- Step 3 · Client Pod
Start a new connection
10.96.0.20:80The client uses the answer as its destination. A successful lookup does not guarantee delivery.
- Step 4 · Service data plane
Choose an eligible endpoint
10.96.0.20:80 → 10.244.3.12:8080A typical Linux Service data plane translates the frontend destination. kube-proxy or its replacement programs this behavior.
- Step 5 · Backend Pod
Receive the application request
targetPort: 8080Pod routing, policy, and the listener must all work. CoreDNS does not carry this request.
Read top to bottom. Dashed arrows show the conceptual sequence, not network calls. Select a numbered node to inspect a step. Scroll sideways on narrow screens to see every participant.
A service proxy selects an eligible EndpointSlice backend and normally rewrites the destination. DNS discovery and packet forwarding are separate steps.
04External → workloadEntry infrastructure plus routing policy
- Step 1 · External client
Connect to the public address
https://api.example.comExternal DNS and reachable entry infrastructure are prerequisites. A Gateway object alone does not provide them.
- Step 2 · Gateway data plane
Accept TLS and match HTTP
Host + path → HTTPRoute backendRefThis example terminates TLS at the Gateway. Its controller has accepted the configuration and programmed a proxy or equivalent data plane.
- Step 3 · Backend selection
Resolve the Service backend
Service port → eligible endpointThe implementation may connect directly to endpoints or use the Service frontend. A ClusterIP or NodePort hop is not universal.
- Step 4 · Backend Pod
Accept the upstream request
Application listenerSource address preservation, health checks, and backend TLS depend on the implementation and configuration.
Read top to bottom. Dashed arrows show the conceptual sequence, not network calls. Select a numbered node to inspect a step. Scroll sideways on narrow screens to see every participant.
The controller implementation determines the real hops, source-address behavior, health checks, and where TLS terminates.
That is enough to explain the web app’s connection to its API. The remaining material is available when you want to inspect a mechanism or investigate a failure.
See the complete system mapOptional detail
When one Pod connects to another, Kubernetes API objects describe the intended addresses, backends, and policy, but they do not carry the packet. The container runtime, Pod network, Service implementation, DNS server, and entry controller each perform part of the work. Two failures can produce the same timeout even when they occur in different layers, so you need both the declared state and the packet path. Kubernetes networking model ↗
For any connection, ask four questions: Who owns the destination address? How did the client discover it? Which data plane forwards the packet? Which policy can allow or reject it?
One request crosses several independently reconciled layers
API objects describe the desired addresses, backends, and policy. Controllers and Node agents program the components that carry the packet.
Kubernetes defines connectivity outcomes, while each cluster chooses how to produce them. Linux bridges, VXLAN, iptables, kube-proxy, and the packet paths shown here are implementation choices rather than universal Kubernetes internals.
Identity for a workload instance
Each Pod receives an address for each configured IP family. Containers in that Pod share its network namespace and port space.
Stable frontend for changing backends
A Service remains addressable while eligible backend Pod addresses change in EndpointSlices.
API objects do not forward packets
Controllers and node agents watch desired state and program an implementation-specific data plane.
Reachability and permission are separate
A valid route does not imply that NetworkPolicy, host filtering, or application policy permits the connection.
Troubleshoot a connection with commands and evidenceOptional detail
Start beside the application, prove the shortest path, and add one layer at a time. If the workload image has no diagnostic tools, use a disposable Pod or ephemeral container in a comparable policy and network context. Plugin and managed-service commands vary, but the order of evidence remains useful.
Application: confirm readiness, listening address, and port. Inspect kubectl get pod -o wide, events, logs, and the process socket from inside the Pod.
Direct Pod path: connect to the destination Pod IP and target port from a relevant source Pod. Failure here bypasses Service and DNS and points toward the app, pod network, or policy.
Backend membership: run kubectl get endpointslice -l kubernetes.io/service-name=<service> -o wide. Check addresses, ports, readiness, and terminating state.
Service frontend: inspect kubectl get svc <service> -o yaml, then test the ClusterIP and Service port. Verify port versus targetPort.
Discovery: query the fully qualified Service name, inspect /etc/resolv.conf, and verify the kube-dns Service plus its EndpointSlices.
Permission: list every policy selecting the source and destination. Confirm the installed implementation enforces the API, then verify which addresses policy observes along paths that also perform NAT.
Node data plane: identify kube-proxy mode or its replacement before inspecting iptables, nftables, eBPF maps, routes, interfaces, conntrack, or plugin-agent logs.
External entry: inspect Service, Gateway, and Route status conditions, controller events/logs, load-balancer health, firewall rules, TLS, and external DNS.
Packet capture points must match the suspected layer. An overlay can show an inner Pod packet on one interface and an outer node-to-node packet on another. A missing packet at the destination is not enough to tell whether routing, encapsulation, policy, or Service selection removed it.
Check common misconceptionsOptional detail
“CNI means VXLAN and a cni0 bridge.”
CNI is a runtime/plugin contract. Bridges and overlays are possible implementations, not requirements.
“kubelet directly configures every Pod interface.”
Kubelet asks the container runtime to create the sandbox; runtimes commonly invoke CNI plugins for networking.
“A Service is a process listening on its ClusterIP.”
The frontend is virtual. A programmed data plane redirects or routes traffic toward eligible endpoints.
“CoreDNS load-balances normal Service traffic.”
For a normal Service, DNS generally returns the stable ClusterIP. Endpoint choice happens in the Service data plane.
“NetworkPolicies are ordered firewall rules.”
Applicable allows are additive. Isolation and permission are evaluated independently for ingress and egress.
“Ingress exposes traffic by itself.”
Ingress is configuration. A compatible controller and its provisioned data plane must implement it.
Explore the twenty detailed scenariosOptional detail
Choose a mechanism you want to inspect. Each example opens independently; you can step through it or read its complete transcript.
Build the network
Start with one container answering one request. Add Pod sandboxes, veth pairs, bridges, cross-node forwarding, and address planes in that order.
You can trace a packet from one Pod to another and name each forwarding hop.Explore example 01Build the networkWhat does the cluster do when a new Pod needs an IP address? Start with how a single Pod gets its identity.
Build the system one piece at a time. Follow a container listening on a port before introducing the network namespace.
- 01One containerListens on a port
- 02Pod sandboxShared environment
- 03Routable IPNeeds cluster identity
- 04CNI PluginWires the network
- 05ReadyCan send and receive
Scenario sequence separate plane, asynchronous step, or conceptual relationship
A container is an isolated Linux process. If it binds to a port, it needs a network interface to receive traffic.
Step 1 of 5
Inspect the evidence and effective setting
EvidenceThis worked example assumes one application container joining a Pod sandbox.
Configuration in playPod spec with one container; kubelet requests network setup from CRI and CNI.
Read every step and alternate example
Start here: one container
Build the system one piece at a time. Follow a container listening on a port before introducing the network namespace.
- One container
A container is an isolated Linux process. If it binds to a port, it needs a network interface to receive traffic.
- Pod sandbox
Kubernetes groups containers into Pods. They share a single network namespace so they can communicate over localhost.
- Routable IP
To talk to other Pods, the Pod needs its own IP address that the rest of the cluster can route to.
- CNI Plugin
The Container Network Interface (CNI) plugin is responsible for connecting the Pod namespace to the node's network.
- Ready
Once wired, the Pod has a full network identity and can participate in cluster traffic.
CNI ADD succeeds
In this veth-based example, the runtime invokes CNI and IPAM supplies an address.
- Sandbox
Kubelet requests a new Pod sandbox through the Container Runtime Interface (CRI).
- NetNS
The container runtime creates the sandbox and, in this Linux example, its network namespace.
- CNI ADD
The runtime invokes the configured CNI plugin chain with an ADD request.
- IPAM
This example's IPAM implementation reserves 10.244.1.15 from its configured pool.
- veth
The plugin creates the veth attachment and configures the Pod-side interface and routes.
Subnet exhausted
IPAM has no free IPs left in the node's allocated CIDR.
- Sandbox
Kubelet requests the sandbox creation as usual.
- NetNS
The network namespace is created and waiting.
- CNI ADD
The CNI ADD command fires to wire up the network.
- IPAM
The local IPAM range is exhausted, so no IP is available and the process fails.
Plugin not found
The CNI binary is missing from the node's disk.
- Sandbox
Kubelet attempts to set up the sandbox.
- CRI config
The runtime reads its configuration to find the CNI plugin.
- Binary search
It searches the configured binary path, usually /opt/cni/bin.
- Missing
The required binary is not found, leaving the Pod without a network attachment.
Explore example 02Same nodeHow does a packet travel between two Pods on the same machine? Watch how traffic avoids the wider network.
In this Linux bridge example, the bridge learns MAC addresses and switches frames locally.
- 01Pod ASends to 10.244.1.8
- 02vethAHost-side peer
- 03cni0 bridgeFDB lookup finds vethB
- 04vethBPeer toward Pod B
- 05Pod BReceives packet
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The Pod sends a packet to a peer address on the same Node.
Step 1 of 5
Inspect the evidence and effective setting
Evidencebridge fdb show br cni0 shows forwarding entries for bridge ports.
Configuration in playBridge attachment and routes come from the installed network implementation.
Read every step and alternate example
Bridge forwarding
In this Linux bridge example, the bridge learns MAC addresses and switches frames locally.
- Pod A
The Pod sends a packet to a peer address on the same Node.
- vethA
The packet crosses the Pod-side interface and host-side veth peer.
- cni0 bridge
In this example, cni0 looks up the destination MAC address in its forwarding database.
- vethB
The bridge sends the frame through the peer connected to Pod B.
- Pod B
Pod B receives the packet without an underlay hop.
eBPF redirect
An eBPF datapath can redirect known local traffic without a Linux bridge.
- Pod A
The source Pod sends the packet through its interface.
- vethA
An eBPF program attached at a kernel hook observes it.
- Kernel redirect
The implementation redirects the packet toward the local destination without using a Linux bridge.
- Pod B
The target Pod receives the packet; the exact hooks and route processing remain implementation-specific.
hostNetwork Pod
The Pod uses the Node network namespace directly.
- Shared netns
The Pod declares hostNetwork and shares the Node network namespace.
- Host interface
It uses Node interfaces and addresses rather than an ordinary Pod veth attachment.
- Port conflict
Its processes share the Node port space and can conflict with host or other host-network processes.
- DNS choice
ClusterFirstWithHostNet is available when the Pod should use cluster-first DNS behavior.
Explore example 03Cross nodeHow does a packet reach a Pod on a different machine? Explore routing and encapsulation.
The underlay network natively routes Pod IPs between nodes.
- 01Pod A10.244.0.5 on Node A
- 02Node A route10.244.1.0/24 via Node B
- 03L3 forwardPacket sent unencapsulated
- 04Node B routeLocal delivery to veth
- 05Pod BReceives 10.244.1.8
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The Pod originates a packet to a destination on another node.
Step 1 of 5
Inspect the evidence and effective setting
Evidenceip route show on Node A shows 10.244.1.0/24 via <nodeB-IP>.
Configuration in playBGP peering or cloud route tables.
Read every step and alternate example
Native routing
The underlay network natively routes Pod IPs between nodes.
- Pod A
The Pod originates a packet to a destination on another node.
- Node A route
The host routing table knows that the destination Pod CIDR is reachable via Node B.
- L3 forward
The packet is forwarded at layer 3 without any encapsulation.
- Node B route
Node B receives it and routes it locally to the target veth interface.
- Pod B
The target Pod receives the unencapsulated packet.
VXLAN overlay
The node wraps the packet in UDP to traverse the underlay.
- Inner packet
The Pod originates the inner packet.
- flannel.1
The flannel/vxlan interface encapsulates it in a UDP VXLAN header.
- Outer packet
The outer packet uses the node IPs to cross the underlay network.
- Decapsulate
Node B receives the UDP packet and decapsulates the inner payload.
- Pod B
The target Pod receives the original inner packet.
Cloud-native ENI
In this AWS VPC CNI example, the Pod receives a VPC-routable address.
- VPC subnet
The network implementation allocates a Pod address from the VPC subnet.
- No overlay
The cloud fabric routes that address without a VXLAN overlay.
- Security scope
By default in this AWS VPC CNI example, Pods share security groups associated with the Node ENIs; per-Pod groups require a separate feature.
- Capacity
Subnet addresses, ENI capacity, prefix delegation, and optional branch interfaces constrain density differently.
Explore example 04MTUWhen does encapsulation overhead silently break large packets? See why small packets work while big ones vanish.
An inner packet can exceed the underlay MTU after tunnel headers are added.
- 01Inner packet1500-byte example
- 02Tunnel headersSize varies by path
- 03Underlay MTU1500-byte example
- 04Too largeFragment, signal, or drop
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The application emits an illustrative 1500-byte inner packet.
Step 1 of 4
Inspect the evidence and effective setting
EvidenceCompare Pod, tunnel, and Node interface MTUs and capture ICMP or ICMPv6 packet-too-big messages.
Configuration in playCNI MTU derived from the real encapsulation and underlay.
Read every step and alternate example
Illustrative VXLAN overhead
An inner packet can exceed the underlay MTU after tunnel headers are added.
- Inner packet
The application emits an illustrative 1500-byte inner packet.
- Tunnel headers
The tunnel adds headers whose size depends on IP family, encapsulation, and optional encryption.
- Underlay MTU
The result exceeds this example's 1500-byte underlay MTU.
- Too large
The network must fragment, return a packet-too-big signal, or drop the packet according to the real path and configuration.
PMTUD succeeds
The sender learns the path MTU via ICMP.
- Packet 1500
The application sends a 1500-byte packet which hits the MTU limit.
- ICMP reply
A router sends back an ICMP 'Fragmentation Needed' message.
- MTU updated
The sender adjusts its Path MTU cache to the lower size.
- Retransmit
The retransmitted packet succeeds at 1450 bytes.
PMTUD blocked
Firewalls drop ICMP, preventing MTU discovery.
- Packet 1500
The application sends a 1500-byte packet which exceeds MTU.
- ICMP reply
The ICMP reply is dropped by an overzealous firewall.
- Black hole
The sender never learns the true MTU and keeps retrying the large packet.
- Stall
The connection hangs indefinitely, though small packets still work.
Find the destination
See how Services, EndpointSlices, DNS, and iptables DNAT transform a name into a routable backend address.
You can explain why DNS success does not prove connectivity.Explore example 05ClusterIPHow does kube-proxy redirect traffic addressed to a virtual Service IP? Follow the destination rewrite.
In kube-proxy iptables mode, kernel rules rewrite the destination before backend routing.
- 01Client sendsTo 10.96.45.3:80
- 02PREROUTINGKUBE-SERVICES match
- 03Service chainSelects backend SEP
- 04DNATRewrites to 10.244.1.7:8080
- 05Pod receivesTarget application
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The client Pod initiates a connection to a virtual ClusterIP.
Step 1 of 5
Inspect the evidence and effective setting
Evidenceiptables-save -t nat shows the KUBE-SVC and KUBE-SEP rules for this Service.
Configuration in playkube-proxy mode=iptables; nftables and replacement proxies expose different state.
Read every step and alternate example
iptables DNAT
In kube-proxy iptables mode, kernel rules rewrite the destination before backend routing.
- Client sends
The client Pod initiates a connection to a virtual ClusterIP.
- PREROUTING
The PREROUTING chain matches the traffic against the KUBE-SERVICES rules.
- Service chain
A probability rule selects a specific backend (KUBE-SEP) for load balancing.
- DNAT
The kernel rewrites the destination IP and port to the actual Pod.
- Pod receives
The target Pod receives the traffic.
No ready endpoints
The Service still has a frontend, but no endpoint is eligible for an ordinary new connection.
- Client sends
The client initiates a connection to the ClusterIP.
- Service frontend
The traffic matches the KUBE-SERVICES chain.
- Eligible set
No backend rules exist because the Service has no ready endpoints.
- Failure
The connection is explicitly rejected or dropped by the node.
Existing connection outlives change
A long-lived flow can retain its chosen backend after endpoint state changes.
- Endpoint changes
A backend Pod dies, and kube-proxy updates iptables to remove it.
- Existing TCP
An existing TCP connection sends another packet.
- Connection state
The connection tracking (conntrack) table remembers the old destination.
- Later result
The packet routes to the dead IP and times out.
Explore example 06EndpointsWhat triggers a change in the endpoints available to a Service? See how readiness gates traffic.
Readiness changes whether the endpoint is ordinarily eligible for new traffic.
- 01Probe passesPod becomes Ready
- 02EndpointSliceready becomes true
- 03Service proxyReconciles endpoint state
- 04New trafficEndpoint becomes eligible
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The Pod's readiness condition becomes true.
Step 1 of 4
Inspect the evidence and effective setting
EvidenceEndpointSlice shows the Pod address with conditions.ready: true after readiness succeeds.
Configuration in playService selector, Pod readiness, and EndpointSlice conditions.
Read every step and alternate example
Pod becomes ready
Readiness changes whether the endpoint is ordinarily eligible for new traffic.
- Probe passes
The Pod's readiness condition becomes true.
- EndpointSlice
The EndpointSlice controller updates the published endpoint's ready condition.
- Service proxy
The installed Service proxy reconciles that endpoint state into its own data plane.
- New traffic
The endpoint becomes eligible for ordinary new Service connections after that reconciliation.
Pod starts terminating
The endpoint remains visible with terminating state while consumers and connections drain.
- Deletion timestamp
The Pod receives a deletion timestamp and begins termination.
- EndpointSlice
The controller exposes terminating=true and ready=false while serving can remain true.
- Service proxy
Service proxies normally avoid the endpoint for ordinary new traffic, with documented fallback when every endpoint is terminating.
- Existing flows
Existing connections and application draining follow their own lifetimes.
- Removed
The endpoint disappears after the Pod is deleted.
Selector changes
Mismatched labels silently disconnect Pods.
- New Pods
New Pods are deployed with a different label.
- Service
The Service selector was not updated to match.
- Mismatch
The EndpointSlice controller ignores the new Pods.
- Old only
Traffic continues to flow only to the old Pods matching the selector.
Explore example 07DNSHow many queries can one name resolution produce? Follow the resolver’s configured search behavior without assuming a fixed count.
The search path resolves local Service names efficiently.
- 01Resolve 'api'0 dots < ndots:5
- 02Search suffixapi.default.svc.cluster.local
- 03CoreDNSAnswers 10.96.45.3
- 04Done1 query total
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The application queries a short name with fewer dots than the ndots threshold.
Step 1 of 4
Inspect the evidence and effective setting
Evidencecat /etc/resolv.conf shows search suffixes and ndots:5.
Configuration in playdnsPolicy: ClusterFirst.
Read every step and alternate example
Short name resolves
The search path resolves local Service names efficiently.
- Resolve 'api'
The application queries a short name with fewer dots than the ndots threshold.
- Search suffix
The resolver appends the first search suffix.
- CoreDNS
CoreDNS matches the full internal name.
- Done
The query succeeds in a single round trip.
External name amplification
A resolver can try search-expanded names before the absolute external name.
- api.example.com
The application gives its resolver an external-looking name that is below the example ndots threshold.
- Search suffixes
The resolver can try one or more search-expanded names according to its search list.
- Negative answers
Negative answers cause the resolver to continue according to its own algorithm.
- Absolute query
The resolver eventually asks for the absolute name; the exact sequence and count are not fixed by Kubernetes.
Headless Service
DNS returns Pod IPs directly instead of a ClusterIP.
- Resolve db
The Service is configured as headless with clusterIP: None.
- CoreDNS
CoreDNS returns the individual Pod IPs directly.
- Pod IPs
The client receives multiple A records.
- Client picks
The client selects one and connects directly without kube-proxy DNAT.
Explore example 08DNS edge casesWhich DNS configuration breaks silently until production traffic hits it? Spot the hidden bottlenecks.
A local daemonset caches queries to avoid conntrack saturation.
- 01Pod resolvesQuery starts
- 02Link-local VIP169.254.20.10
- 03DaemonSetAnswers from cache
- 04No conntrackAvoids UDP limit
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The Pod initiates a DNS query.
Step 1 of 4
Inspect the evidence and effective setting
Evidence/etc/resolv.conf nameserver is 169.254.20.10 instead of cluster DNS IP.
Configuration in playNodeLocalDNSCache DaemonSet.
Read every step and alternate example
NodeLocal DNSCache
A local daemonset caches queries to avoid conntrack saturation.
- Pod resolves
The Pod initiates a DNS query.
- Link-local VIP
Traffic routes to a special link-local IP on the node.
- DaemonSet
A local DaemonSet answers directly from memory.
- No conntrack
No cross-node UDP traffic or conntrack entries are created.
Default-deny kills DNS
Egress policies block DNS resolution by default.
- egress: []
A strict NetworkPolicy blocks all egress by default.
- UDP 53
The Pod attempts a DNS query to kube-dns.
- Dropped
The policy drops the UDP packet.
- Timeout
The application times out, making it look like a general network failure.
FQDN trailing dot
A trailing dot marks the name as absolute for ordinary DNS resolver behavior.
- api.example.com.
The application includes a trailing dot in its query.
- Absolute name
An ordinary DNS resolver treats the name as absolute.
- Direct lookup
Search suffixes are not appended, although retries and record-type lookups can still produce multiple exchanges.
Control the traffic
Follow traffic policy, source IP behavior, Gateway API attachment, and TLS termination as external traffic enters the cluster.
You can identify where source address translation occurs and which component inspects the request.Explore example 09Traffic policyHow does traffic policy change which backends can receive a connection? Separate a hard Local constraint from softer topology preferences.
Cluster policy makes ready endpoints across the cluster eligible.
- 01Policy: ClusterDefault behavior
- 02Node A1 local endpoint
- 03Node B2 remote endpoints
- 04Eligible setAll 3 available
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The Service uses the default Cluster traffic policy.
Step 1 of 4
Inspect the evidence and effective setting
EvidenceInspect EndpointSlices and the rules or maps used by the installed Service proxy.
Configuration in playinternalTrafficPolicy: Cluster (default).
Read every step and alternate example
Cluster-wide eligibility
Cluster policy makes ready endpoints across the cluster eligible.
- Policy: Cluster
The Service uses the default Cluster traffic policy.
- Node A
Node A contributes one ready endpoint.
- Node B
Node B contributes two ready endpoints.
- Eligible set
All three are eligible, but connection reuse, affinity, and proxy behavior mean request distribution need not be even.
Node-local only
Internal traffic stays with ready endpoints on the same Node or is dropped.
- Policy: Local
The Service uses the Local traffic policy.
- Node A (1 Pod)
A client on Node A can use its ready local endpoint.
- Node C (0 Pods)
Node C has no ready local endpoint.
- Dropped
kube-proxy drops traffic on Node C rather than falling back to a remote endpoint.
External Local
Local policy can preserve a client address by avoiding the extra Node hop.
- External traffic
External traffic reaches a Node for a Service using Local policy.
- Local endpoint
The receiving Node needs an eligible local endpoint.
- No cross-node hop
Avoiding the extra Node hop can avoid the common source-NAT path.
- Backend observes
The backend source address must still be verified against the load-balancer and Service implementation.
Explore example 10Source IPWhere does the client address get replaced, and what sees the replacement? Trace NAT transformations.
A common NodePort path SNATs cross-node external traffic for symmetric return routing.
- 01Client 203.0.113.5Arrives at Node A
- 02Node pathMay SNAT to Node A
- 03ForwardTo Pod on Node B
- 04Pod observesPath-dependent source
Scenario sequence separate plane, asynchronous step, or conceptual relationship
In this common NodePort path, an external connection lands on Node A.
Step 1 of 4
Inspect the evidence and effective setting
EvidenceApplication logs and a packet capture at the backend establish the address actually observed.
Configuration in playexternalTrafficPolicy: Cluster plus load-balancer and Service-proxy implementation.
Read every step and alternate example
Cluster policy example
A common NodePort path SNATs cross-node external traffic for symmetric return routing.
- Client 203.0.113.5
In this common NodePort path, an external connection lands on Node A.
- Node path
Node A source-NATs traffic that it forwards to another Node.
- Forward
The translated connection reaches a backend Pod on Node B.
- Pod observes
The backend observes Node A as the transport source; provider and proxy implementations can differ.
Local policy example
A compatible implementation can preserve the source by routing only to a local endpoint.
- Client 203.0.113.5
An external connection lands on a Node with a local endpoint.
- Local endpoint
Local policy keeps this Service hop on the receiving Node.
- No Node SNAT
The common kube-proxy path can avoid source NAT here.
- Pod observes
The backend can observe the client source when the surrounding load balancer also preserves it.
Proxy protocol
L7 proxies insert the client IP into headers.
- L7 Proxy
A layer 7 proxy terminates the client connection.
- X-Forwarded-For
A trusted proxy can add the original client address to Forwarded or X-Forwarded-For.
- SNAT
The separate upstream connection has the proxy as its transport source.
- Pod reads header
The application must trust only headers supplied by known proxies and parse them correctly.
Explore example 11Gateway APIWhich status condition tells you where the Gateway API request path broke? Read from the infrastructure inward.
The class, listener, Route attachment, and backend reference are accepted and programmed.
- 01GatewayClassAccepted
- 02Gateway listenerAccepted + Programmed
- 03HTTPRoute parentAccepted for listener
- 04backendRefResolvedRefs true
- 05Data planeTest actual traffic
Scenario sequence separate plane, asynchronous step, or conceptual relationship
A controller accepts the GatewayClass.
Step 1 of 5
Inspect the evidence and effective setting
Evidencekubectl get gateway,httproute -o yaml shows conditions for the current object generation.
Configuration in playGatewayClass, Gateway listeners, HTTPRoute parent status, and backend references.
Read every step and alternate example
Full attachment succeeds
The class, listener, Route attachment, and backend reference are accepted and programmed.
- GatewayClass
A controller accepts the GatewayClass.
- Gateway listener
The Gateway listener reports Accepted and Programmed for the current generation.
- HTTPRoute parent
The HTTPRoute reports Accepted for the intended parent and listener.
- backendRef
ResolvedRefs confirms that the backend reference exists and is permitted.
- Data plane
An end-to-end request confirms that the programmed data plane is actually reachable.
Route attachment rejected
Namespace boundaries block route attachment.
- HTTPRoute
The HTTPRoute is in the app-team namespace.
- Gateway
The Gateway is in the infra namespace.
- allowedRoutes
The Gateway only allows routes from its own namespace.
- Rejected
The route is rejected for crossing namespace boundaries.
Cross-namespace backend
Backend references across namespaces require explicit grants.
- HTTPRoute
The HTTPRoute is in Namespace A.
- backendRef
It points to a Service in Namespace B.
- No Grant
Namespace B has no ReferenceGrant allowing this.
- Rejected
The reference is rejected as insecure.
Explore example 12TLSWhich component holds the private key, and what can the routing layer inspect? Compare termination with passthrough.
The Gateway decrypts traffic and can route using HTTP request attributes.
- 01Client TLSEncrypted
- 02GatewayHolds listener certificate
- 03InspectReads host/path
- 04Backend hopHTTP or separately secured
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The client initiates a TLS connection.
Step 1 of 4
Inspect the evidence and effective setting
EvidenceGateway listener status and tls.mode: Terminate with valid certificateRefs establish the listener configuration.
Configuration in playGateway listener TLS termination plus explicit backend transport policy.
Read every step and alternate example
Terminate at Gateway
The Gateway decrypts traffic and can route using HTTP request attributes.
- Client TLS
The client initiates a TLS connection.
- Gateway
The Gateway terminates that connection using the listener certificate.
- Inspect
It can inspect HTTP attributes and choose a route.
- Backend hop
The upstream hop uses whatever backend transport the implementation and policy configure; it is a separate security boundary.
TLS passthrough
The gateway routes based on SNI without decrypting.
- Client TLS
The client initiates a TLS connection.
- Gateway SNI
The Gateway reads only the SNI hostname from the unencrypted handshake.
- Encrypted TCP
It forwards the encrypted TCP stream unmodified.
- Pod terminates
The backend Pod holds the certificate and terminates the TLS.
Backend TLS
The Gateway terminates the client connection and starts a separately authenticated TLS connection upstream.
- Client TLS
The client initiates TLS to the Gateway.
- Gateway terminates
The Gateway terminates that connection and inspects the HTTP request.
- New TLS
It starts a distinct TLS connection and validates the configured backend identity.
- Backend
The backend terminates the upstream connection using its own certificate.
Enforce the boundaries
Apply NetworkPolicy isolation, selector logic, default-deny egress, and implementation-specific NAT ordering.
You can identify the address a policy observes instead of assuming that policy always runs before or after NAT.Explore example 13IsolationWhen does creating a NetworkPolicy actually change what traffic is allowed? Default open vs explicit deny.
Default Kubernetes allows all traffic.
- 01Pod AInitiates
- 02Pod BNon-isolated
- 03AllowedDefault open
Scenario sequence separate plane, asynchronous step, or conceptual relationship
Pod A initiates a connection.
Step 1 of 3
Inspect the evidence and effective setting
Evidencekubectl get networkpolicy -A returns nothing.
Configuration in playNo NetworkPolicy resources.
Read every step and alternate example
No policy exists
Default Kubernetes allows all traffic.
- Pod A
Pod A initiates a connection.
- Pod B
Pod B has no NetworkPolicy selecting it.
- Allowed
Traffic is allowed because default behavior is open.
Ingress policy selects destination
Selecting a Pod turns on implicit deny for it.
- Policy
A NetworkPolicy selects Pod B, isolating it for ingress.
- Pod B
Pod B is now isolated and implicitly denies unmatched traffic.
- Pod A
Pod A is not explicitly allowed.
- Blocked
The connection is blocked by the policy.
Both sides isolated
Egress and ingress are evaluated independently.
- Egress policy
An egress policy restricts Pod A.
- Ingress policy
An ingress policy restricts Pod B.
- Both must allow
Both policies must explicitly allow the connection.
- Success
The connection succeeds only if both sides agree.
Explore example 14SelectorsWhy does one YAML change turn a narrow allow into a wide-open rule? See how arrays change logic.
Multiple array elements act as an OR.
- 01from arrayTwo elements
- 02Rule 1podSelector app=web
- 03Rule 2namespace env=staging
- 04AllowedAny web OR any staging
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The from block uses multiple array elements.
Step 1 of 4
Inspect the evidence and effective setting
EvidenceA monitoring Pod in staging can reach this Service.
Configuration in playNetworkPolicy ingress.from as array.
Read every step and alternate example
OR logic: two array elements
Multiple array elements act as an OR.
- from array
The from block uses multiple array elements.
- Rule 1
One element allows the web label.
- Rule 2
Another element allows the staging namespace.
- Allowed
Traffic is allowed from any web Pod OR any Pod in staging.
AND logic: single element
Combining selectors in one element acts as an AND.
- from array
The from block uses a single array element.
- Condition 1
It specifies both a podSelector and a namespaceSelector.
- Condition 2
They are combined with logical AND.
- Allowed
Traffic is allowed only from web Pods IN the staging namespace.
ipBlock with except
ipBlock matches CIDRs but except creates holes.
- cidr
The ipBlock specifies a broad CIDR.
- except
The except field carves out a subset.
- Result
It allows traffic from node IPs but blocks the Pod network.
Explore example 15DNS + policyWhy does default-deny egress often make DNS the first visible failure? Account for the dependencies an application needs before it can connect.
Egress block hits DNS first.
- 01egress: []Deny all
- 02Port 53Blocked
- 03Name resolutionFails completely
- 04App failsLooks like network error
Scenario sequence separate plane, asynchronous step, or conceptual relationship
A NetworkPolicy drops all egress traffic.
Step 1 of 4
Inspect the evidence and effective setting
Evidencenslookup kubernetes.default times out.
Configuration in playNetworkPolicy egress: [] (empty = deny all).
Read every step and alternate example
Default deny blocks DNS
Egress block hits DNS first.
- egress: []
A NetworkPolicy drops all egress traffic.
- Port 53
The DNS query on port 53 is blocked.
- Name resolution
Name resolution completely fails.
- App fails
The application fails because it can't resolve endpoints.
Allow DNS only
DNS resolves but application traffic still drops.
- Rule 1
An egress rule explicitly allows DNS.
- Resolution
Name resolution now succeeds.
- App traffic
But traffic to the resolved IPs is still blocked by default.
- Timeout
Connections time out during establishment.
Minimal working policy
App requires explicit egress rules for each dependency.
- Rule 1
The policy allows DNS.
- Rule 2
The policy also explicitly allows the API dependency.
- Success
Traffic flows to the existing service.
- New service
New dependencies will fail until the policy is updated again.
Explore example 16NAT + policyWhich source address does an ipBlock rule actually evaluate? Inspect the deployed order instead of assuming pre-NAT or post-NAT behavior.
One implementation evaluates policy before a later source rewrite.
- 01Pod packetSource 10.244.0.5
- 02Policy hookEvaluates original source
- 03Later NATMay rewrite for next hop
- 04Rule resultMatches Pod CIDR
Scenario sequence separate plane, asynchronous step, or conceptual relationship
A Pod sends a packet using its Pod source address.
Step 1 of 4
Inspect the evidence and effective setting
EvidencePolicy counters and packet captures on both sides of the enforcement hook reveal the effective order.
Configuration in playNetwork plugin, Service implementation, cloud path, and enforcement hook.
Read every step and alternate example
Policy sees original source
One implementation evaluates policy before a later source rewrite.
- Pod packet
A Pod sends a packet using its Pod source address.
- Policy hook
This implementation evaluates NetworkPolicy before a later translation point.
- Later NAT
A subsequent hop may still rewrite the address.
- Rule result
The CIDR rule therefore matched the original source in this particular path.
Policy sees rewritten source
Another path can rewrite the source before policy evaluates the packet.
- Original client
An external client begins with its own source address.
- Entry NAT
An entry proxy or Node rewrites the source before the enforcement point.
- Policy hook
The policy evaluates the address it observes at that point.
- Rule result
A rule written for the original client range does not match.
Use workload selectors
Pod and namespace selectors express an in-cluster workload relationship.
- namespaceSelector
The policy first narrows callers to namespaces with the intended label.
- podSelector
A Pod selector in the same peer entry further narrows that set.
- Policy identity
The policy expresses an in-cluster workload relationship rather than a transient Pod address.
- Allowed
Matching workloads are allowed without relying on an external CIDR rule.
Read the incident
Combine mechanisms when connections fail, overlays break, or multiple systems change at once.
You can locate the first failed layer and choose evidence that belongs to it.Explore example 17ConnectionThe connection times out. Which layer stopped the packet? Differentiate routing failures from app crashes.
The Pod phase alone does not prove that the expected socket is accepting connections.
- 01Pod RunningAt least one container active
- 02Expected socketNothing bound to :8080
- 03ReadinessShould become false
- 04Service backendEventually ineligible
- 05Direct testRefused or reset
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The Pod phase is Running because at least one container remains active.
Step 1 of 5
Inspect the evidence and effective setting
Evidencess -lntp in the application container and container status identify the listener and process state.
Configuration in playApplication bind address, container lifecycle, and readiness probe.
Read every step and alternate example
App not listening
The Pod phase alone does not prove that the expected socket is accepting connections.
- Pod Running
The Pod phase is Running because at least one container remains active.
- Expected socket
No process is listening on the expected application socket.
- Readiness
A suitable readiness check becomes false.
- Service backend
EndpointSlice and Service-proxy consumers converge on making that backend ineligible.
- Direct test
A direct connection helps separate listener failure from Service and DNS state.
Port mismatch
Service targetPort doesn't match container port.
- Service port 80
The Service defines port 80 for clients.
- targetPort 8080
It rewrites the destination to targetPort 8080.
- Container 3000
The container process actually listens on 3000.
- Refused
The connection is refused because nothing listens on 8080.
Half-working NodePort
Local traffic policy breaks NodePorts without local endpoints.
- Node A
Node A has a local backend Pod.
- Node A NodePort
Node A's NodePort works properly.
- Node B
Node B has no local backend Pods.
- Node B NodePort
Node B's NodePort fails because the Local policy prevents cross-node forwarding.
Explore example 18OverlaySame-node Pods connect but cross-node Pods time out. What broke? Troubleshoot the tunnel.
The overlay tunnel entrance is missing.
- 01flannel.1Interface down
- 02Same-nodeBridge forwarding works
- 03Cross-nodeDropped before tunnel
- 04TimeoutNo path
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The vxlan/flannel interface is missing or down.
Step 1 of 4
Inspect the evidence and effective setting
Evidenceip link show flannel.1 returns 'Device not found'.
Configuration in playFlannel/Calico VXLAN interface.
Read every step and alternate example
VXLAN interface down
The overlay tunnel entrance is missing.
- flannel.1
The vxlan/flannel interface is missing or down.
- Same-node
Same-node traffic still works via bridge forwarding.
- Cross-node
Cross-node traffic is dropped before entering the tunnel.
- Timeout
Connections time out.
Missing native route
In this native-routing design, the source Node lacks a route for the remote Pod prefix.
- Route missing
The routing table lacks an entry for the remote Pod CIDR.
- Default gateway
Packets are sent to the default gateway.
- Lost
The underlay network drops them as unroutable.
- Timeout
Connections time out.
Firewall blocks VXLAN port
Underlay firewalls block overlay tunnel traffic.
- UDP 4789
UDP port 4789 is used for VXLAN encapsulation.
- Blocked
A cloud security group blocks this port between nodes.
- Same-node
Same-node traffic works fine.
- Cross-node
Cross-node traffic times out because tunnels are blocked.
Explore example 19iptablesHow do you read the kube-proxy iptables chain hierarchy during an outage? Follow the probability rules.
The chain structure is inspectable even though endpoint choice is probabilistic for a new connection.
- 01KUBE-SERVICESMatches Service frontend
- 02KUBE-SVC-XXXXEnters Service chain
- 03ProbabilityChooses one endpoint
- 04KUBE-SEP-AAAAApplies DNAT
- 05PostroutingMasquerades when required
Scenario sequence separate plane, asynchronous step, or conceptual relationship
The iptables Service rules match the configured frontend.
Step 1 of 5
Inspect the evidence and effective setting
Evidenceiptables-save -t nat shows the Service and endpoint chains for iptables mode.
Configuration in playkube-proxy mode=iptables; other proxy modes use different evidence.
Read every step and alternate example
Successful DNAT walk
The chain structure is inspectable even though endpoint choice is probabilistic for a new connection.
- KUBE-SERVICES
The iptables Service rules match the configured frontend.
- KUBE-SVC-XXXX
Traffic enters the chain generated for that Service and port.
- Probability
A statistic rule chooses one endpoint for the new connection.
- KUBE-SEP-AAAA
The endpoint chain applies destination NAT.
- Postrouting
Postrouting applies masquerading only when the path requires it.
Service deleted, conntrack stale
Deleted Services can still serve existing flows.
- Service deleted
The Service is deleted and its chains are removed.
- New connection
New connections fail immediately.
- Old connection
Conntrack keeps existing flows active.
- Works temporarily
Traffic temporarily continues until the flow times out.
Rule count explosion
Too many Services slow down iptables sync.
- 15000+ rules
Thousands of Services create tens of thousands of rules.
- Sync slow
kube-proxy takes longer to sync changes.
- Latency spike
Latency spikes occur during mass updates.
Explore example 20CompoundWhich layer broke first when multiple systems changed at once? Untangle overlapping incidents.
A fast process exit can outrun endpoint and proxy convergence.
- 01Rolling updateOld Pod gets deletion timestamp
- 02EndpointSliceterminating=true, ready=false
- 03ConsumersReconcile on their schedules
- 04Process exitsBefore drain completes
- 05Requests failDuring the gap
Scenario sequence separate plane, asynchronous step, or conceptual relationship
A rollout gives an old Pod a deletion timestamp.
Step 1 of 5
Inspect the evidence and effective setting
EvidenceCorrelate Pod lifecycle events, EndpointSlice conditions, proxy metrics, and request failures by timestamp.
Configuration in playReadiness, preStop behavior, termination grace period, rollout strategy, and entry-controller draining.
Read every step and alternate example
Poor shutdown during rollout
A fast process exit can outrun endpoint and proxy convergence.
- Rolling update
A rollout gives an old Pod a deletion timestamp.
- EndpointSlice
EndpointSlice exposes terminating state while readiness becomes false.
- Consumers
Service proxies and entry controllers reconcile that change on their own schedules.
- Process exits
The process exits before every relevant drain and connection has completed.
- Requests fail
Requests can fail during that poorly coordinated interval; the rollout itself does not require an outage.
Headless DNS + backend change
A cached headless answer can retain an old Pod address after membership changes.
- Headless lookup
A headless Service lookup returns endpoint addresses rather than one stable ClusterIP.
- Client cache
The client keeps an older DNS answer according to its cache behavior.
- Endpoint changes
EndpointSlice membership changes while that answer remains cached.
- Existing connection
Existing application connections have a separate lifetime from the DNS record.
- Refresh + reconnect
A later lookup and new connection use the current endpoint set.
Policy + routing compound
Both ingress and egress policies must be fixed.
- Ingress blocked
Namespace B applies an ingress policy blocking Namespace A.
- Fix ingress
The operator fixes the ingress policy.
- Egress blocked
Namespace A has a restrictive egress policy.
- Still blocked
Traffic is still blocked.
- Success
Success requires both sides to allow it.
For a closer look at a particular subsystem, see Pod networking and CNI, Services, DNS, or Gateway API and Ingress.
Sources and documentation
- Kubernetes networking model
- Cluster networking and address ranges
- Pods and shared network namespaces
- Kubernetes network plugins
- CNI specification
- Kubernetes Services
- EndpointSlices
- Virtual IPs and Service proxies
- DNS for Services and Pods
- NetworkPolicy
- Kubernetes Ingress
- Gateway API introduction
- Gateway API troubleshooting and status
- Service source IP behavior
- Service internal traffic policy
- Debug Services
- Debug DNS resolution
- NodeLocal DNSCache
- Amazon EKS security groups for Pods