Skip to main content

Assignment 1: Deploy a stateless app and expose it

Goal: Deploy a stateless web app to the lab cluster as a Deployment, configure it with a ConfigMap, give it a stable internal address with a Service, and expose it on a hostname through the Kong ingress — the full stateless app chain.

Where: From the Jumpbox, where kubectl, helm, and k9s are installed and the kubeconfig is ready. The cluster is master 10.100.100.7 with workers 10.100.100.8/.9/.10; ingress goes through the Kong gateway at 10.100.100.100.

Tasks

  1. Create your own namespace to keep your work tidy: kubectl create namespace <yourname> and use -n <yourname> (or set it as your context's default) for everything below.
  2. Write a ConfigMap named web-config with at least two keys, e.g. APP_GREETING and LOG_LEVEL.
  3. Write a Deployment named web with replicas: 3 running nginx:1.27 (or any small web image). Give the Pods the label app: web. Inject APP_GREETING from the ConfigMap as an environment variable using valueFrom.configMapKeyRef.
  4. Apply it and confirm all 3 Pods are Running and spread across nodes: kubectl get pods -o wide -n <yourname>.
  5. Write a Service named web of type ClusterIP with selector: app: web, port: 80, targetPort: 80. Confirm it has endpoints: kubectl get endpoints web -n <yourname> (must not be empty).
  6. From a throwaway Pod, verify the Service answers by DNS name: kubectl run tmp --image=busybox:1.36 -it --rm -n <yourname> -- wget -qO- http://web
  7. Write an Ingress named web with ingressClassName: kong, host web.example.com, path / Prefix, backend Service web port 80. Apply it and check kubectl describe ingress web -n <yourname>.
  8. Do a rolling update: change the image tag (e.g. to nginx:1.28), apply, and watch kubectl rollout status deploy/web -n <yourname>. Then practice a rollback: kubectl rollout undo deploy/web -n <yourname>.
  9. Scale the Deployment to 5 replicas and back to 3 using kubectl scale.

Deliverable

A folder of YAML manifests (configmap.yaml, deployment.yaml, service.yaml, ingress.yaml) that, applied in order with kubectl apply -f ., brings the whole app up in your namespace. Include a short README.md listing the exact commands you ran to verify each step (Tasks 4, 6, 7, 8) and paste the key command outputs.

Acceptance criteria — you're done when:

  • A namespace named after you exists and holds all your objects.
  • kubectl get deploy web -n <yourname> shows 3/3 ready.
  • kubectl get pods -o wide -n <yourname> shows Pods running on more than one worker node.
  • The Pods receive APP_GREETING from the ConfigMap (prove with kubectl exec <pod> -n <yourname> -- env | grep APP_GREETING).
  • kubectl get endpoints web -n <yourname> lists 3 endpoint IPs (Service selector matches Pod labels).
  • The throwaway-Pod wget http://web returns the nginx page.
  • kubectl get ingress web -n <yourname> shows class kong and host web.example.com.
  • You performed a rolling update and a rollback, captured in your README.
  • Applying all manifests fresh into an empty namespace works with kubectl apply -f ..

Hints

  • Endpoints empty? Your Service selector does not match the Pod labels. They must be identical key/value pairs.
  • Re-read the Networking lesson for the Deployment -> Service -> Ingress chain diagram.
  • Use kubectl explain deployment.spec and kubectl explain ingress.spec.rules to discover field names without guessing.
  • kubectl apply -f . applies every YAML in the current directory — keep one object per file with clear names.
  • Watch things live with k9s if you prefer a TUI over repeated kubectl get.
  • Blocked for >~30 min after re-reading the lessons? Bring what you've tried to your mentor.