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
| Word | What it means | Example |
|---|---|---|
| Service | one steady name and address for a group of pods | |
| Label | a tag on a pod, a key and a value | app=pages |
| Selector | the labels a Service looks for on pods | |
| Cluster DNS | the cluster's own phone book of names | |
| Target port | the 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
| Pod | Its labels | Picked by app=pages? |
|---|---|---|
| pages-a | app=pages | Yes |
| pages-b | app=pages | Yes |
| mailer-a | app=mailer | No, the value differs |
| old-a | none | No, the label is missing |
The cells students fill in are left blank in this preview.
Make a namespace for the site
kubectl create namespace siteShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Start three web servers
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
kubectl rollout status deployment/pages -n siteShown 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
kubectl expose deployment pages -n site --name=pages-svc --port=80 --target-port=8080Shown 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
kubectl get endpointslices -n site -l kubernetes.io/service-name=pages-svc -o jsonpath='{.items[*].endpoints[*].addresses[0]}' | wc -wShown 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
kubectl create service clusterip lost -n site --tcp=80:8080Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Count the pods behind lost
kubectl get endpointslices -n site -l kubernetes.io/service-name=lost -o jsonpath='{.items[*].endpoints[*].addresses[0]}' | wc -wShown 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
kubectl run probe -n site --rm -i --restart=Never --image=busybox:1.37.0 -- wget -qO- http://pages-svcShown 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
kubectl run probe -n site --rm -i --restart=Never --image=busybox:1.37.0 -- nslookup pages-svc.site.svc.cluster.localShown 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
kubectl run probe -n site --rm -i --restart=Never --image=busybox:1.37.0 -- cat /etc/resolv.confShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Remove the namespace
kubectl delete namespace siteShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.