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.

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

  • 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.

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

--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

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:

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

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

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.

Layered debugging replaces guesswork with small proofs. That skill transfers to every distributed application you will build.

Reference

Official references

Just started Saved in this browser.