Catalog
All 30 stages in one place — filter by difficulty or verification status, or search. Click any row for the stage's concept note and the diff the reference solution adds at that stage.
- 30Stages
- 30✓ Verified
- 10Hard
- 1Course
What "verified" means: ✓ Verified — the stage has a reference solution checked in that passed stages 1..N cumulatively against a live kind cluster in CI. CI re-verifies every snapshot on each push, so a drifted assertion fails the build rather than the reader.
Status
| ✓ | Stage | Level | What it teaches |
|---|---|---|---|
| Build your own kubectl 30/30 verified ▸ | |||
| ✓ | 1. Find the cluster | Easy | Before a client can do anything it has to answer "which server, as whom?", and the answer is never hardcoded.▸ |
| ✓ | 2. Choose a context | Easy | A context is a named triple: a cluster, a user, and optionally a namespace.▸ |
| ✓ | 3. Ask the server what it is | Medium | This is the first request that leaves your machine, and it deliberately goes through the discovery client rather than a typed one.▸ |
| ✓ | 4. List the pods | Easy | The first real read. A typed clientset gives you a method per resource — CoreV1().Pods(ns).List(...) — which returns *corev1.PodList with real Go fields.▸ |
| ✓ | 5. Choose a namespace | Medium | Namespace resolution has three steps and the middle one is the trap: --namespace, then whatever the current context carries, then "default".▸ |
| ✓ | 6. Print a table | Medium | A table is a user interface, and the property that makes it one is that the columns line up when the names do not.▸ |
| ✓ | 7. Humanise the age | Medium | The API stores a creation timestamp; a person reading a hundred rows wants "2d".▸ |
| ✓ | 8. Print the object as JSON | Medium | -o json is not "your table, as JSON". It is the API's own object, verbatim — apiVersion, kind, metadata, spec, status, managedFields and all.▸ |
| ✓ | 9. Print the object as YAML | Medium | Same object, different serializer — and the way you get there matters.▸ |
| ✓ | 10. Look everywhere at once | Medium | -A is not a client-side filter and it is not a loop over namespaces.▸ |
| ✓ | 11. Ask for one object | Easy | Get and List are different endpoints with different failure modes, and the difference is the lesson. A List of an empty namespace succeeds and returns nothing.▸ |
| ✓ | 12. Ask what the server serves | Medium | This is the request that makes a client general. Nothing in your program knows what a Pod is: the server reports its groups, the versions in each, and the resources in those —…▸ |
| ✓ | 13. Resolve any spelling | Hard | po, pod, pods, Pod, pods.v1. — five spellings of one thing, and the API accepts exactly one of them in a URL.▸ |
| ✓ | 14. Get anything at all | Hard | This is the largest single step in the course: your program stops being a pod client. The dynamic client speaks in GVRs and unstructured.▸ |
| ✓ | 15. Wider columns | Easy | -o wide adds the columns that only make sense for a particular resource: a Pod's node and IP, a Service's cluster IP and ports.▸ |
| ✓ | 16. Filter by label | Medium | Labels are the identifying metadata everything in Kubernetes coordinates through: a Service finds its pods by selector, a Deployment owns its ReplicaSets by selector.▸ |
| ✓ | 17. Filter by field | Medium | Field selectors look like label selectors and are a different axis.▸ |
| ✓ | 18. A stable order | Easy | The API returns items in whatever order the storage layer hands them over.▸ |
| ✓ | 19. Keep watching | Hard | A watch is a long-lived HTTP response the server keeps appending to, one JSON event per change: ADDED, MODIFIED, DELETED, BOOKMARK, ERROR.▸ |
| ✓ | 20. Delete an object | Easy | The first write, and the lesson is that delete is asynchronous. The call returns when the server has accepted the request and marked the object — not when it is gone.▸ |
| ✓ | 21. Create from a manifest | Hard | A manifest is self-describing: it carries apiVersion and kind, which is why kubectl create -f needs no flag saying what is in the file.▸ |
| ✓ | 22. Apply, not create | Hard | Apply is not "create if missing, update if present". It is a different claim: these fields should look like this, and I am the one saying so.▸ |
| ✓ | 23. Two managers, one field | Hard | When your apply sets a field another manager already owns, the server answers 409 Conflict and changes nothing.▸ |
| ✓ | 24. Change one field | Medium | Patch is the smallest write verb: the body names only what changes, so nothing has to be read first and there is no resourceVersion to conflict on.▸ |
| ✓ | 25. Scale through a subresource | Medium | /scale is a subresource: a separate endpoint on the same object, with its own tiny schema.▸ |
| ✓ | 26. Describe one object | Medium | Describe answers a different question from get, and the difference explains the format.▸ |
| ✓ | 27. Attach its events | Hard | Events are the cluster's explanation of why, and the surprise is that they are not part of the object they describe.▸ |
| ✓ | 28. Stream a container's logs | Hard | There is no Log object to Get. pods/log is a subresource that returns a stream of bytes, and with --follow it never ends — which is why its client-go signature could not have…▸ |
| ✓ | 29. Run a command inside | Hard | Exec needs several independent byte streams at once — stdin, stdout, stderr and a terminal-resize channel — multiplexed over a single connection. Ordinary HTTP/1.▸ |
| ✓ | 30. Forward a local port | Hard | Port-forward is the same upgrade as exec put to a different use: a local listener whose connections are tunnelled, one stream pair per forwarded port, through the apiserver to the…▸ |
No stages match — clear the search or change filters.