Lab 13 - Services and DNS
Lab 13 - Services and DNS
Goal: reach Pods by a stable name, from inside and from outside. Chapter: Networking, CNI, Services and DNS
# 1 - something to expose
cd ~
kubectl create deploy web --image nginx:1.27 --replicas 3
kubectl get pods -l app=web -o wide # note the Pod IPs
# 2 - ClusterIP, the default
kubectl expose deploy web --port 80 --name web-svc
kubectl get svc web-svc
kubectl get endpointslices -l kubernetes.io/service-name=web-svc
The EndpointSlice is the interesting object: it holds the three Pod IPs. The Service is just a stable front; the EndpointSlice is the live membership list, maintained by a controller as Pods become ready.
# 3 - reach it by name from inside the cluster
kubectl run tmp --image busybox:1.36 --restart=Never -it --rm -- \
wget -qO- --timeout=3 web-svc | head -3
# 4 - what DNS actually returns
kubectl run tmp --image busybox:1.36 --restart=Never -it --rm -- \
nslookup web-svc.default.svc.cluster.local
The name resolves to the ClusterIP, not to a Pod. Traffic to that virtual IP is rewritten by kube-proxy on the node to one of the real Pod IPs.
# 5 - stability: destroy every Pod, keep the address
kubectl get svc web-svc -o jsonpath='{.spec.clusterIP}{"\n"}'
kubectl delete pod -l app=web
kubectl get pods -l app=web -o wide # all new IPs
kubectl get svc web-svc -o jsonpath='{.spec.clusterIP}{"\n"}' # unchanged
kubectl get endpointslices -l kubernetes.io/service-name=web-svc # new IPs inside
That is the whole value proposition: the Pods are cattle, the Service name is not.
From outside the cluster
# 6 - NodePort opens the same port on EVERY node
kubectl delete svc web-svc
kubectl expose deploy web --port 80 --type NodePort --name web-svc
PORT=$(kubectl get svc web-svc -o jsonpath='{.spec.ports[0].nodePort}')
echo $PORT
for n in control01 worker01 worker02 worker03; do
echo -n "$n: "; curl -s --max-time 3 http://$n:$PORT | grep -o '<title>.*</title>'
done
Every node answers, including nodes running none of the Pods - kube-proxy forwards for the whole cluster. Note how quickly this gets unmanageable with more than a couple of applications, which is the argument for the Gateway API in Lab 16.
# 7 - port-forward, for debugging only
kubectl port-forward svc/web-svc 8080:80 &
curl -s localhost:8080 | head -3
kill %1
port-forward runs on your workstation and dies with the terminal. Useful for
poking at something that has no external access; never part of a solution.
Discovery
InfodiscoverTask A. Create namespace backend with a Deployment api (nginx:1.27)
and a ClusterIP Service api. From a Pod in default, reach it by name.
Expected: the nginx welcome page.
Task B. Break the Service: change its selector to app=nothing. What do
the EndpointSlice and a request show? Fix it again.
Task C. Which mode does kube-proxy run in on this cluster?
Clean up
# 8 -
kubectl delete svc web-svc
kubectl delete deploy web
kubectl delete ns backend --ignore-not-found