Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Kubernetes Services and cluster DNS

After this lesson: I can give pods one name and find it from another pod.

55 min lesson11 commandsKubernetes lab: a one-node k3s cluster for each student on a private Ubuntu VM

A Service gives pods one name

A Kubernetes Service gives a group of pods one steady name and one steady address. It matters because pods come and go and their own addresses change, so without a Service nothing could find them.

Behind the name, the Service spreads each request over the pods that are ready.

By the end of this lesson

Note

I can give pods one name and find it from another pod.

Key words

WordWhat it meansExample
Serviceone steady name and address for a group of pods
Labela tag on a pod, a key and a valueapp=pages
Selectorthe labels a Service looks for on pods
Cluster DNSthe cluster's own phone book of names
Target portthe port the pods listen on

The cells students fill in are left blank in this preview.

A selector picks pods by their labels

Every pod made by a Deployment carries a label, a key and a value. Here the label is app=pages.

A Service has a selector, which is a list of labels. It sends requests to every ready pod that has all of them. The Service never lists pod names. It looks at labels again each time pods change.

Worked example: which pods the selector picks

PodIts labelsPicked by app=pages?
pages-aapp=pagesYes
pages-bapp=pagesYes
mailer-aapp=mailerNo, the value differs
old-anoneNo, the label is missing

The cells students fill in are left blank in this preview.

Make a namespace for the site

Command
kubectl create namespace site

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Start three web servers

Command
kubectl create deployment pages -n site --image=busybox:1.37.0 --replicas=3 --port=8080 -- sh -c 'mkdir -p /www; echo "page from $HOSTNAME" > /www/index.html; exec httpd -f -p 8080 -h /www'

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Wait until all three are ready

Command
kubectl rollout status deployment/pages -n site

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Give them a Service called pages-svc

Command
kubectl expose deployment pages -n site --name=pages-svc --port=80 --target-port=8080

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A Service sends to the pods it matches

The pods a Service currently reaches are kept in an endpoint list. The Run below counts the addresses in it. It prints 3, one for each web server.

Then a second Service is made whose selector is app=lost. No pod has that label, so it reaches none.

Count the pods behind pages-svc

Command
kubectl get endpointslices -n site -l kubernetes.io/service-name=pages-svc -o jsonpath='{.items[*].endpoints[*].addresses[0]}' | wc -w

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Make a Service that matches no pod

Command
kubectl create service clusterip lost -n site --tcp=80:8080

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Count the pods behind lost

Command
kubectl get endpointslices -n site -l kubernetes.io/service-name=lost -o jsonpath='{.items[*].endpoints[*].addresses[0]}' | wc -w

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A common mistake

Warning

Many people think a Service always works once it exists. It only reaches pods its selector matches. A selector with a typo, or a different label from the pods, makes a Service with no pods behind it, and every request is refused. Count the endpoints first.

Cluster DNS turns the name into an address

Inside the cluster, a program asks the name pages-svc and cluster DNS answers with the Service's address. The full name is pages-svc.site.svc.cluster.local: service, namespace, then the cluster's own ending.

A pod's search line adds its own namespace, so inside site the short name is enough. The next Runs use a throwaway pod called probe, which is deleted when it finishes.

Fetch the page by its name

Command
kubectl run probe -n site --rm -i --restart=Never --image=busybox:1.37.0 -- wget -qO- http://pages-svc

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Ask cluster DNS for the full name

Command
kubectl run probe -n site --rm -i --restart=Never --image=busybox:1.37.0 -- nslookup pages-svc.site.svc.cluster.local

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Read the pod's DNS settings

Command
kubectl run probe -n site --rm -i --restart=Never --image=busybox:1.37.0 -- cat /etc/resolv.conf

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Remove the namespace

Command
kubectl delete namespace site

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

About this lab and its source: Kubernetes lab: a one-node k3s cluster for each student on a private Ubuntu VM

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.