Skip to main content

K8s Katas

Focused, repeatable YAML-writing drills designed to build fluency in Kubernetes primitives. Complete each kata multiple times until the setup feels automatic. Grade yourself by applying your result to a real cluster and seeing it work.

Kata 1: Hardened Deployment with Requests, Limits, and Probes

Time limit: 15 minutes
Goal: Write a production-shaped Deployment from scratch
Setup: Open an empty editor, no reference material

Write a Deployment payments that:

  • runs image myorg/payments:2.3.1 with 3 replicas
  • sets requests: { cpu: 250m, memory: 256Mi } and limits: { cpu: 500m, memory: 512Mi }
  • defines both a liveness probe (GET /healthz every 10s, failureThreshold: 3) and a readiness probe (GET /ready every 5s, failureThreshold: 2)
  • runs as non-root UID 1000, drops all capabilities, uses a read-only root filesystem with an emptyDir mounted at /tmp
  • mounts a ConfigMap payments-config as env and a Secret payments-creds as env

Repeat until: You can produce a syntactically valid manifest without reference and explain every field.

Kata 2: Service + Ingress for Two Microservices

Time limit: 15 minutes
Goal: Expose two apps behind one hostname with path-based routing
Setup: Two Deployments already exist: web (port 80) and api (port 8080), both labeled app: <name>.

Produce:

  • a ClusterIP Service for each Deployment
  • an Ingress public on host app.example.com with ingressClassName: nginx that routes / (Prefix) to web and /api (Prefix) to api
  • a TLS stanza referencing Secret app-tls

Repeat until: The YAML applies cleanly, and a curl through the ingress controller reaches the expected backend for each path.

Kata 3: StatefulSet for a Three-Node Database

Time limit: 20 minutes
Goal: Stable identity plus per-Pod persistent storage
Setup: StorageClass gp3 exists

Produce:

  • a headless Service db (clusterIP: None) selecting app: db, port 5432
  • a StatefulSet db with 3 replicas, serviceName: db, image postgres:16
  • a volumeClaimTemplates entry named data requesting 20Gi ReadWriteOnce from gp3, mounted at /var/lib/postgresql/data
  • terminationGracePeriodSeconds: 60 and a readiness probe that checks pg_isready

Repeat until: You can produce this from memory and explain why every field is required and what would go wrong if you used a Deployment instead.

Kata 4: RBAC Policy for a CI Service Account

Time limit: 15 minutes
Goal: Write a least-privilege RBAC configuration
Setup: Namespace prod exists. A CI pipeline needs to deploy applications.

Produce:

  • a ServiceAccount ci-deployer in prod
  • a Role in prod that permits get, list, watch, create, update, patch on deployments, replicasets, services, and configmaps -- and nothing else
  • a RoleBinding attaching the Role to the ServiceAccount
  • a written explanation (3-5 sentences) of why delete is deliberately missing, and why a ClusterRole would be wrong here

Repeat until: You can produce the manifests from memory and defend the scope in front of a skeptical reviewer.

Completion Standard

  • Can complete each kata within the time limit
  • Every kata applies cleanly and passes kubectl apply --dry-run=server
  • Can explain every field in every manifest without reference
  • Can justify each choice (why a StatefulSet and not a Deployment; why a Role and not a ClusterRole; why this set of probes)