Skip to main content

Kubernetes Hands-on Exercises — Manage the Restaurant

Time to stop reading and start doing. These exercises require a Kubernetes cluster. The easiest way is minikube (local) or kind (Docker-based).

How to follow

Install minikube first (minikube start), then type the commands one by one and read the output.

Exercise 0 · Setup — Connect to the Restaurant​

Start minikube
minikube start
Check cluster is running
kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:8443
Check nodes
kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 30s v1.28.x
Remember

minikube gives you a single-node cluster locally. It's perfect for learning and exercises.

Exercise 1 · First Deployment — Hire Your First Chef​

create deployment.yaml
cat > deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: campus-library
spec:
replicas: 2
selector:
matchLabels:
app: campus-library
template:
metadata:
labels:
app: campus-library
spec:
containers:
- name: web
image: nginx:alpine
ports:
- containerPort: 80
EOF
Apply it
kubectl apply -f deployment.yaml
deployment.apps/campus-library created
See the Pods
kubectl get pods
NAME READY STATUS RESTARTS AGE
campus-library-7d4b8c9f-x2k4m 1/1 Running 0 10s
campus-library-7d4b8c9f-a9n3p 1/1 Running 0 10s
See the Deployment
kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
campus-library 2/2 2 2 30s
Remember

You created 2 Pods with one command. If one dies, the Deployment replaces it automatically.

Exercise 2 · Service — Open the Order Window​

create service.yaml
cat > service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
name: campus-library-svc
spec:
selector:
app: campus-library
ports:
- port: 80
targetPort: 80
type: NodePort
EOF
Apply it
kubectl apply -f service.yaml
See the Service
kubectl get svc campus-library-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
campus-library-svc NodePort 10.96.123.45 <none> 80:31234/TCP 5s
Test it
curl $(minikube service campus-library-svc --url)
<!DOCTYPE html>
<html>
<head><title>Welcome to nginx!</title>...
Remember

The Service gives a stable address. Even if Pods are replaced, the Service IP and DNS name stay the same.

Exercise 3 · Scaling — Hire More Chefs​

Scale to 5
kubectl scale deployment campus-library --replicas=5
Watch new Pods appear
kubectl get pods -w
NAME READY STATUS AGE
campus-library-7d4b8c9f-x2k4m 1/1 Running 5m
campus-library-7d4b8c9f-a9n3p 1/1 Running 5m
campus-library-7d4b8c9f-q8w2r 0/1 ContainerCreating 0s
campus-library-7d4b8c9f-m3j5n 0/1 ContainerCreating 0s
campus-library-7d4b8c9f-k8p2w 0/1 ContainerCreating 0s

After a few seconds, all 5 should be Running.

Scale back to 2
kubectl scale deployment campus-library --replicas=2
Remember

Scaling is instant. Kubernetes creates or removes Pods based on the replica count you specify.

Exercise 4 · Update and Rollback — Change the Menu​

Update the image to a new version
kubectl set image deployment/campus-library web=nginx:1.25-alpine
Watch the rollout
kubectl rollout status deployment/campus-library
deployment "campus-library" successfully rolled out
See the history
kubectl rollout history deployment/campus-library
REVISION CHANGE-CAUSE
1 <none>
2 <none>
Rollback to the previous version
kubectl rollout undo deployment/campus-library
deployment.apps/campus-library rolled back
Remember

rollout undo is instant. Old ReplicaSets are kept for exactly this purpose.

Exercise 5 · Debugging — Inspect the Kitchen​

See Pod details
kubectl describe pod $(kubectl get pods -l app=campus-library -o jsonpath='{.items[0].metadata.name}')

Look for the Events section at the bottom — this tells you what Kubernetes did with the Pod.

See logs
kubectl logs $(kubectl get pods -l app=campus-library -o jsonpath='{.items[0].metadata.name}')
127.0.0.1 - - [10/Oct/2024:12:00:00 +0000] "GET / HTTP/1.1" 200 615 "-"
Open a shell inside the Pod
kubectl exec -it $(kubectl get pods -l app=campus-library -o jsonpath='{.items[0].metadata.name}') -- sh
/ # exit
Remember

When something goes wrong: kubectl get pods → kubectl describe pod <name> → kubectl logs <name>. This is the debugging trifecta.

Exercise 6 · Cleanup — Close the Restaurant​

Delete everything
kubectl delete -f service.yaml
kubectl delete -f deployment.yaml
Verify
kubectl get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10m
Remember

Deleting the Deployment removes all its Pods. Deleting the Service removes the stable address. Always clean up after exercises.