Kubernetes lab: a one-node k3s cluster for each student on a private Ubuntu VM
This lab gives each student a Kubernetes cluster of their own. k3s, a small Kubernetes, runs on the student’s one Ubuntu VM as a single node, and the student works with the real kubectl command: they run web servers with a Deployment, watch Kubernetes bring back a pod that is deleted, give the pods one name with a Service, feed them a ConfigMap, and find out why a pod will not run.
Nothing is installed on the student’s computer and nothing is shared with other students: a mistake costs one cluster, and the lab can be started again.
What students learn
What Kubernetes does: you say what should be running, and it keeps it running. In five parts. First a look around the cluster, its node, its namespaces and the pods Kubernetes starts itself. Then a Deployment of three web servers, scaled up and down and with a pod deleted to see it come back. Then a Service, which gives the pods one name that another pod finds through the cluster’s own DNS. Then a ConfigMap, whose words end up in each page, and the fact that a running pod does not see a change until it is replaced. Last three Deployments that are broken, each in a different way, to be fixed by reading kubectl describe and kubectl logs.
What is in the machine
One node, k3s version 1.35, installed by the lab’s setup from the k3s project’s public releases on GitHub. The files are pinned by their checksums, the ones the release publishes, and any other file is refused. Traefik, the service load balancer and the metrics server are switched off to fit in memory, so there is no Ingress and no kubectl top. kubectl, crictl and ctr are there.
A student’s VM reaches Ubuntu’s package archive, PyPI, npm and GitHub, and no image registry. So every pod in this lab runs the one image that comes with k3s, busybox version 1.37.0, which has sh, httpd, wget and nslookup, and that is all the lessons need. A pod that asks for an image such as nginx stays in ImagePullBackOff, which the README says in its first lines.
Run it in your browser
VM labs are set as a lab task in a module, and the sample is on the lab’s page. The machine asks for 2 CPUs, 2 GB of memory and 10 GB of disk. k3s uses about half a gigabyte when nothing runs on it, and the rest is for the pods and Ubuntu.
- Add the lab. In a module you teach, add a task and choose the Ubuntu VM lab card. The page shows a short description of the machine instead of a compose file.
- Start from the sample. The page offers ready-made labs to start from. Choose Kubernetes with k3s. Using a sample replaces the text, and Undo brings yours back.
- Publish and start your own copy. Publish, then Start. The lab’s own setup script installs k3s from its public GitHub releases the first time the VM starts, about 270 MB, and writes the k3slab command, the two files to work on and the README. The cluster is ready a few minutes later.
- Open the terminal. Open its terminal, run k3slab status until it says the cluster is ready, and read README.md in the home folder: it says what to do in five parts and gives none of the answers.
Who can run it
The lab needs the 2 GB, which is the machine a college account gets. For a free account the machine is 1 GB: the lab does not start k3s by itself there and says so, and sudo k3slab install --anyway is for a student who wants to try, with no promise that it holds. A visitor with no account has 1 GB and reaches Ubuntu’s archive alone, so k3s cannot be downloaded at all. Set the lab for a class in a college.
A basic lesson on this lab
Kubernetes Basics is a small lesson worked in this lab, which is an Ubuntu VM. It has a hook, an I can outcome, key words, a starter, a check after each idea, a common mistake and an exit check, and each step has a Run button that types its command into the machine’s terminal. A student reads the node and the system pods, makes a Deployment of three pods, deletes the pods and watches three new ones appear, and scales to five.
The lesson works in a namespace of its own and deletes it, and leaves the lab’s own task, the Service, the ConfigMap and the broken Deployments, to the student, so it hands out no answers.
How it is marked
The lab has a check. It runs on a copy of the saved machine after a fresh start, waits for k3s to come up with the student’s work still in it, and asks the cluster, not the files. The Deployment web must be three ready pods and the Service web must send port 80 to port 8080 of all three. A pod in the cluster then asks http://web twelve times: the name must work, the answers must come from more than one pod, and each page must show the ConfigMap’s words. Then the check changes the ConfigMap to a word nobody has seen and deletes a pod: the Deployment must bring one back whose page shows the new word, which a page typed into the Deployment never does. Last the three broken Deployments must run, and the third must say in its log that it is ready. The first line of what the check printed says why it did not pass.
The check has three minutes, so a student should stop the lab with the cluster running and leave it to start.
- Hand it out. Assign the lab like any task, with a due date if you want one. Each student gets a VM of their own, kept between sessions, and the cluster is on its disk.
- Run the check. On a student’s row in the class list, press Run the check. It starts a copy of their saved machine that is not saved back, waits for the cluster to come up, asks it and shows whether it passed, what it printed and when. The student is not told the result.
- Mark it. Read the first line of what the check printed: it says what is not right, such as no Service called web, a page that does not show the ConfigMap, or a broken Deployment that still does not run. Send the work back with a reason if it needs more.
The definition on GitHub
The file is the whole lab definition, the same text the platform runs: size, setup script, the k3slab command, the two files to work on, README and check. Copy it and change the Deployments, or the faults in broken.yaml, to make a longer lab.
Try this lab, and what it costs
A free personal account can work through the basic lessons in this lab, with enough free credit each month to follow most lessons and no card. For a class, a school or college has its first 365 days free for up to 50 students, then pays per student a year, with every lab included and staff free.
Questions people ask
- Does the Kubernetes lab need a licence?
- No. k3s is open source under the Apache 2.0 licence and is downloaded from the k3s project’s own releases when the student’s VM starts; nothing of it is distributed by us. The images in its package are the project’s own and are not changed.
- Why do the pods use busybox and not nginx?
- A student’s VM reaches no image registry, so a pod can only run an image the machine already has. k3s brings a small set with it, and busybox is the one that does something useful: it serves a web page, fetches one and looks up names. Everything about Deployments, Services and ConfigMaps is the same whatever the image is.
- Can students harm anything?
- Only their own copy. The cluster is one node inside the VM, which reaches Ubuntu’s archive, PyPI, npm and GitHub and nothing else. If a student breaks the cluster, k3slab files puts the two files back, and kubectl delete namespace lab starts the exercises again.
- Can a student with a free account use it?
- Not reliably. A free account’s machine has 1 GB and k3s needs about 2 GB with a few pods, so the lab does not start it by itself on that machine. A college account’s machine has 2 GB, which is what the lab asks for.
- Was the lab tested in a real student VM?
- The setup with its real downloads, the lesson’s commands and the check, with every way of faking it, were run in a real Ubuntu 26.04 with k3s running, in a container standing in for the VM. A booted student VM, which starts k3s from a systemd unit, with 2 GB and the platform’s own network proxy, is worth one try before a class.