web stats
Featured image of post Install K8sQuest on Linux with Podman Rootless: Cgroups Solution

Install K8sQuest on Linux with Podman Rootless: Cgroups Solution

How to fix the 'Delegate=yes' error when installing K8sQuest using Kind and Podman rootless on Linux, and how to get started.

Recently I came across K8sQuest. It is a gamified learning platform where we get familiar with Kubernetes through different missions, where something will break… and we will have to diagnose and fix it. It runs completely locally, using Kind (Kubernetes in Docker/Podman) to spin up under the hood the cluster we will interact with.

When running the installer, it tries to install the cluster with Kind, but since I use Podman in rootless mode (without root privileges) on my machine, I hit a wall in the form of an error:

1
2
3
๐Ÿ”ง Creating Kubernetes cluster...
enabling experimental podman provider
ERROR: failed to create cluster: running kind with rootless provider requires setting systemd property "Delegate=yes", see [https://kind.sigs.k8s.io/docs/user/rootless/](https://kind.sigs.k8s.io/docs/user/rootless/)

In this post we will see why this happens, how to fix it, and some brief guidance on how to start playing with K8sQuest in our Linux environment.

The problem: Systemd and Cgroups delegation

When we use Kind with Podman rootless, the system tries to create containers that act as “nodes” of our Kubernetes cluster. These nodes need to manage their own CPU and memory limits using cgroups v2.

By default, and for security reasons, systemd blocks a normal user from delegating these controls. Although the official documentation recommends modifying systemd configuration files or using systemctl --user, these solutions often fail silently or are simply not the easiest ones.

The solution

Instead of fighting with global session configuration or restarting services randomly, the most effective way that worked for me is to inject the permission directly at the moment of running the installer.

To do this, we wrap our installation script with systemd-run. This tool allows us to launch a process by creating a “scope” (an ephemeral environment) where we pass exactly the property it needs: Delegate=yes.

We move to the directory of the cloned K8sQuest repository and run the installation like this:

1
systemd-run --scope --user -p "Delegate=yes" ./install.sh

When executing it, you will see a brief message indicating that it is running as a systemd unit (e.g. Running as unit: run-XXXX.scope), and then the installation will continue without issues until completion, creating the cluster correctly and all the required K8sQuest dependencies.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
โฏ systemd-run --scope --user -p "Delegate=yes" ./install.sh
Running as unit: run-r2e1b14ae02bf40a7bc0041218fe81c35.scope; invocation ID: 40e8bc6093734d0da4ec058c445ef224
๐ŸŽฎ K8sQuest Installation
========================

โœ… Python 3.14 detected
โœ… Prerequisites OK

๐Ÿ“ฆ Installing Python dependencies...

[notice] A new release of pip is available: 26.0 -> 26.0.1
[notice] To update, run: pip install --upgrade pip
โœ… Python packages installed

enabling experimental podman provider
No kind clusters found.
๐Ÿ”ง Creating Kubernetes cluster...
enabling experimental podman provider
Creating cluster "k8squest" ...
 โœ“ Ensuring node image (kindest/node:v1.35.0) ๐Ÿ–ผ 
 โœ“ Preparing nodes ๐Ÿ“ฆ  
 โœ“ Writing configuration ๐Ÿ“œ 
 โœ“ Starting control-plane ๐Ÿ•น๏ธ 
 โœ“ Installing CNI ๐Ÿ”Œ 
 โœ“ Installing StorageClass ๐Ÿ’พ 
Set kubectl context to "kind-k8squest"
You can now use your cluster with:

kubectl cluster-info --context kind-k8squest

Have a nice day! ๐Ÿ‘‹
Switched to context "kind-k8squest".
๐Ÿ—๏ธ  Setting up k8squest namespace...
namespace/k8squest created
๐Ÿ›ก๏ธ  Configuring safety guards (RBAC)...
serviceaccount/k8squest-player created
role.rbac.authorization.k8s.io/k8squest-player-role created
rolebinding.rbac.authorization.k8s.io/k8squest-player-binding created
clusterrole.rbac.authorization.k8s.io/k8squest-viewer created
clusterrolebinding.rbac.authorization.k8s.io/k8squest-viewer-binding created
โœ… Safety guards configured

๐Ÿš€ Setup Complete!

To start playing, use the shortcut:
  ./play.sh

Getting started with K8sQuest

Once the installer has finished, we already have our cluster up and running in Podman completely transparently and without compromising the security of our system by using the root account.

To start working with it, the usual steps are:

  • Verify the cluster

We can make sure the Kind cluster has been created correctly by checking the nodes (remember that if you use Podman, you might need to export the KUBECONFIG variable if the installer indicated it):

1
kubectl get nodes

You should see the K8sQuest node(s) in Ready state.

1
2
3
4
โฏ kubectl get nodes
Alias tip: k get nodes
NAME                     STATUS   ROLES           AGE     VERSION
k8squest-control-plane   Ready    control-plane   5m40s   v1.35.0
  • Start the game

To start the game, we just need to open a terminal in the directory with the K8sQuest files and run:

1
./play.sh

play_sh

After accepting, our first mission will begin: “Fix the Crashing Pod”

Primera mision

Primera mision descripcion

It gives a series of very important instructions to be able to play:

  • We must open a new terminal window/tab where we will “play”

  • We will use the kubectl command to apply the solutions

  • We will return to this tab to verify the solution.

  • Run K8sQuest

Since the entire cluster is contained within our Podman user environment, it can be managed comfortably. If at any point we need to stop the cluster to free up system resources, it can be done using the Kind CLI indicating the experimental provider:

1
KIND_EXPERIMENTAL_PROVIDER=podman kind delete cluster --name k8squest

With all this, we now have a functional, lightweight, and secure Kubernetes environment on our Linux to keep tinkering and learning with K8sQuest. See you in the next post!

Victory


PS: The banner image of this post has been generated with AI.

comments powered by Disqus
Built with Hugo-Extended & theme Stack