Appendix

Appendix: DNS, HTTP, and TCP/IP

Build a practical mental model for names, addresses, ports, connections, requests, and Kubernetes networking.

Just started Saved in this browser.

When a page cannot reach an API, “the network” is too broad a diagnosis. Work layer by layer: name resolution, IP reachability, TCP connection, HTTP exchange, then browser policy.

Last updated: 2026-07-20

Audience

Who this chapter is for

This appendix is for beginners who have (or can deploy) the full-stack Minikube release and want a repeatable debugging habit. Basic Chapter 9 knowledge helps but is not mandatory if you run the prepare block below.

Step by step

Download this chapter's files

Use your browser to download either ivia-chapter-11.tar.gz or ivia-chapter-11.zip. The archive is self-contained; you do not need this tutorial repository.

Open a terminal after the browser download:

cd ~/Downloads
tar -xzf ivia-chapter-11.tar.gz
cd ivia-chapter-11

All remaining relative paths in this chapter start from that extracted directory.

Do this

The challenge

Challenge: trace one request to the backend from DNS name through TCP connection to HTTP response and identify the layer of any failure.

Prepare

Prerequisites

  • A terminal with kubectl and curl.
  • A running Minikube cluster; the package includes a full-stack release to deploy if needed.
  • nslookup or dig for host DNS checks.
Outcome

Learning goals

After this chapter, you will be able to:

  • Distinguish DNS from routing
  • Distinguish IP addresses from ports
  • Distinguish TCP from HTTP
  • Distinguish cluster DNS from public DNS
  • Distinguish HTTP failures from CORS enforcement
Step by step

Prepare a traceable release

If simple-app is not already deployed, create it from this package:

minikube addons enable ingress
kubectl label node minikube ivia.ch/nodetype=app --overwrite
minikube image build -t simple-backend:local fullstack-app/backend
minikube image build -t simple-frontend:local fullstack-app/frontend
helm upgrade --install simple-app \
  oci://harbor.ivia.ch/ivia-generic-helm-chart/ivia-generic-helm-chart \
  --version 4.8.0 -n tutorial --create-namespace \
  --atomic --timeout 5m \
  -f fullstack-app/values.yaml
Step by step

A layered request

  1. DNS maps a name such as api.simple-app.test to an IP address.
  2. IP routes packets between network interfaces.
  3. TCP establishes an ordered byte stream to a port such as 80 or 8080.
  4. HTTP sends a method, path, headers, and optional body over that connection.
  5. CORS is a browser policy applied to cross-origin HTTP responses; curl does not enforce it.

Kubernetes adds two useful abstractions. A Service has a stable virtual IP and DNS name despite changing Pod IPs. Ingress examines HTTP hostnames and paths, then forwards to a Service.

Diagnostic story: start outside the cluster (hosts/--resolve → TCP → HTTP), then move inside (Service DNS → port-forward). Stop at the first layer that fails.

Step by step

Trace from your computer

MINIKUBE_IP=$(minikube ip)
printf 'Minikube IP: %s\n' "$MINIKUBE_IP"
nslookup api.simple-app.test || true
curl --verbose --resolve api.simple-app.test:80:$MINIKUBE_IP \
  http://api.simple-app.test/health

Expected observations: Minikube prints an IP; nslookup may fail for .test names (that is fine if you use --resolve); verbose curl shows Connected to, GET /health, and HTTP 200 with JSON.

--resolve supplies a temporary DNS answer for curl. In verbose output, find the chosen IP, Connected to, the request line GET /health, the Host header, the response status, and JSON body.

Test raw TCP availability without sending HTTP:

nc -vz "$MINIKUBE_IP" 80

You should see a successful connection to port 80. If nc is unavailable, curl's connection lines provide the same practical checkpoint.

Step by step

Trace inside Kubernetes

Start a temporary DNS client Pod. We do this because cluster DNS names are not the same as your laptop’s hosts file.

kubectl run dns-check -n tutorial --rm -it --restart=Never \
  --image=registry.k8s.io/e2e-test-images/dnsutils:1.3 -- \
  nslookup simple-app-backend.tutorial.svc.cluster.local

You should see an address answer for the Service. The complete Service name means: Service simple-app-backend, namespace tutorial, Service zone svc, cluster domain cluster.local.

Forward the Service and bypass ingress:

kubectl port-forward service/simple-app-backend 8080:8080 -n tutorial

In another terminal:

curl --verbose http://localhost:8080/health

Expect HTTP 200. If direct Service forwarding works but ingress does not, investigate Ingress, host resolution, or its controller—not the backend process.

Verify

Expected validation

The host trace connects to Minikube port 80 and receives HTTP 200 from /health. Cluster DNS returns a Service address. Port forwarding also returns 200. You should be able to name the first failed layer if one check differs.

Troubleshoot

Troubleshooting and common pitfalls

  • DNS answer exists but connection is refused: naming worked; inspect the destination port, process, Service endpoints, and firewall.
  • TCP connects but HTTP is 404: transport worked; check Host header, route, and path.
  • HTTP succeeds in curl but browser fails: inspect CORS, mixed content, certificates, and browser console.
  • Pod IP used directly: Pod IPs are replaceable. Use a Service name inside the cluster.
  • localhost ambiguity: it always refers to the current network namespace—the host, a container, or a Pod depending on where the command runs.
  • ICMP ping fails: many systems block ping while TCP/HTTP works; test the protocol you actually need.
Practice

Recap and practice

Recap: Prove DNS, then TCP, then HTTP, then browser policy. Cluster DNS and laptop DNS are different systems.

Try to explain in your own words:

  1. What does a successful nc to port 80 prove that HTTP 200 does not yet prove?
  2. Why might ingress fail while kubectl port-forward to the Service still works?

Exercise: Intentionally use the wrong Host header with curl and note whether you get a different HTTP status.

Stretch: From the dnsutils Pod, resolve the frontend Service name and compare it to the backend Service name.

Reference

Official references

Just started Saved in this browser.