Korab CenajTechnical articleAll articles

Kubernetes networking · 3 min read

Tracing DNS to Pod in Kubernetes

“The Service is healthy” is a tempting conclusion when its selector resolves to a ready endpoint. That proves one control-plane relationship. A client request still depends on naming, address advertisement, ingress routing, port translation, policy, TLS, and application behavior agreeing from the client’s location.

Troubleshoot contracts, not objects

  1. DNS answer
  2. Load-balancer address
  3. Ingress route
  4. Service mapping
  5. EndpointSlice backend
  6. Pod network
  7. Application response

The misconception occurs because Kubernetes presents each abstraction as an independently reconciled resource. Green status nearby is easy to mistake for end-to-end health. A better model treats the path as ordered contracts: the client resolves the intended address; that address reaches the correct ingress; host and path rules choose the Service; its port maps to the intended target port; the EndpointSlice selects an eligible pod; policy and the dataplane carry the connection; the TLS peer proves the expected identity; and the application answers a meaningful request.

Locate the first broken handoff

Start with declared intent and walk in request order, comparing each output with the next input. Query DNS from the same resolver context as the affected client; split-horizon zones and stale caches can make a correct answer elsewhere irrelevant. Match the answer to the advertised load-balancer address, then match ingress host, path, Service name, and port. Resolve a named targetPort against the container declaration and inspect EndpointSlices. Consider this illustrative report: these Kubernetes objects agree, but no active request or handshake was made. Calling the application healthy here would skip three untested contracts.

Example: illustrative and sanitized
Service → EndpointSlice → Pod: PASS
Ready endpoints: 1 · targetPort: 3000
Cilium agents: 5/5 ready
Observed flow: NOT COLLECTED
TLS handshake: NOT RUN
Application probe: NOT RUN
Conclusion: backend relation declared; application result unknown

Three boundaries matter most

EndpointSlice readiness means an endpoint is eligible to receive Service traffic; it is not a verdict on application correctness. A shallow readiness probe may pass while a database-backed operation fails. Likewise, a NetworkPolicy object describes intended connectivity under the cluster’s policy implementation. Static analysis can reveal selectors and apparent allowances, but it is not observed traffic; Cilium L7 conclusions require relevant Hubble flows or another runtime observation. Finally, a Certificate resource, cert-manager Ready condition, or TLS Secret proves neither what ingress serves nor what a client accepts. Full TLS proof requires connecting with the intended SNI, inspecting the served chain and hostname, checking validity and trust, and completing the negotiated handshake. Even a successful HTTP probe covers only that route, protocol, source, and moment.

Practical checks for a bounded diagnosis

Stop at the narrowest supported conclusion

The goal is not to make every stage green; it is to identify the earliest contract that fails and avoid claiming more than each check establishes. The Kubernetes Service Path Analyzer case study applies this path model with Kubernetes discovery and optional bounded probes. Its point-in-time reports separate object relationships from active DNS, flow, TLS, and application observations, so the next troubleshooting step remains explicit. A ready endpoint is useful routing information; application health remains a separate, deliberately tested conclusion. That boundary makes escalation faster and more precise.