A small app is three objects working together
A small app on Kubernetes is a Deployment, a Service and a ConfigMap working together. Each does one job, and the app works only when the three are joined correctly.
This lesson builds one from nothing and shows exactly where the joins are, because that is where the mistakes hide.
By the end of this lesson
Note
I can run a small app that uses a Deployment, a Service and a ConfigMap together.
Key words
| Word | What it means | Example |
|---|---|---|
| Manifest | a description of the objects you want, as text | |
| Apply | send a manifest to the cluster to make it so | |
| Selector | the labels a Deployment or Service looks for on pods | |
| Port | a numbered door a program listens on | 8080 |
| Probe pod | a throwaway pod used to test from inside |
The cells students fill in are left blank in this preview.
Three objects, three joins
The Deployment keeps the pods running. The ConfigMap holds the settings. The Service gives the pods a name.
They are joined in three places. The Service finds pods by a label. The Service sends to the port the pods listen on. The Deployment reads its settings from the ConfigMap by name and key.
Worked example: the three joins
| Join | One side says | The other side must have |
|---|---|---|
| Service to pods | selector: app=board | Pod labels with app=board |
| Service to port | targetPort: 8080 | A container listening on 8080 |
| Deployment to settings | ConfigMap board-config, key TITLE | That ConfigMap, with that key |
The cells students fill in are left blank in this preview.
Make a namespace for the app
kubectl create namespace boardShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Make the settings
kubectl create configmap board-config -n board --from-literal=TITLE=NoticesShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Make the Deployment, with no pods yet
kubectl create deployment board -n board --image=busybox:1.37.0 --replicas=0 --port=8080 -- sh -c 'mkdir -p /www; echo "$TITLE from $HOSTNAME" > /www/index.html; trap "exit 0" TERM; httpd -f -p 8080 -h /www & wait'Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Join the Deployment to the ConfigMap
kubectl set env deployment/board -n board --from=configmap/board-configShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
See the Service as a manifest
kubectl expose deployment board -n board --port=80 --target-port=8080 --dry-run=client -o yamlShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Make the Service for real
kubectl expose deployment board -n board --port=80 --target-port=8080Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Start two pods
kubectl scale deployment board -n board --replicas=2Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Wait until both are ready
kubectl rollout status deployment/board -n boardShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Test the app from inside the cluster
The Service is reachable only from inside the cluster, so a throwaway pod asks it. The first Run counts how many different pods answer twenty requests. With two pods, it prints 2.
The second Run fetches one page. Its first word is the ConfigMap's TITLE, and the rest names the pod that answered.
Count the pods that answer twenty requests
kubectl run probe -n board --rm -i --restart=Never --image=busybox:1.37.0 -- sh -c 'for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do wget -qO- http://board; done | sort -u | wc -l'Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Fetch one page by the Service name
kubectl run probe -n board --rm -i --restart=Never --image=busybox:1.37.0 -- wget -qO- http://boardShown 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 the three objects are joined by their names. Only the ConfigMap is. The Service and the Deployment are joined by labels, and the port is a number. A typo in a label, a port or a key makes no error at all. The app just does not work.
Change a setting and replace the pods
Settings are read when a pod starts. So a changed TITLE reaches the page only after the pods are replaced.
The next Runs change TITLE, delete both pods so the Deployment starts two new ones, wait for them, and fetch the page again.
Change TITLE to Events
kubectl patch configmap board-config -n board --type merge -p '{"data":{"TITLE":"Events"}}'Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Delete both pods
kubectl delete pods -n board -l app=board --grace-period=1Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Wait for the new pods
kubectl wait --for=condition=Ready pod -l app=board -n board --timeout=60sShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Fetch the page again
kubectl run probe -n board --rm -i --restart=Never --image=busybox:1.37.0 -- wget -qO- http://boardShown 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 boardShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.