Skip to main content

Fixing Kind Cluster Creation Failure Due to cgroup v1 on Windows with Docker Desktop and WSL2

· 4 min read
Sarat Kota
Cloud Engineer

While setting up my Kubernetes learning environment using Kind, I encountered an issue where the cluster creation failed during the control plane initialization. This post documents the problem, the investigation process, and the final solution.

Environment​

  • Host OS: Windows 11
  • WSL Version: 2.3.24.0
  • Kernel Version: 5.15.153.1-2
  • Docker Desktop: 4.80.0
  • Docker Engine: 29.6.1
  • Kind: v0.31.0
  • Kind Node Image: kindest/node:v1.35.0

Kind configuration:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4

nodes:
- role: control-plane
- role: worker
- role: worker

The Problem​

Running the following command:

kind create cluster --config kind-config.yaml

failed with the error:

[kubelet-check] Waiting for a healthy kubelet at http://127.0.0.1:10248/healthz. This can take up to 4m0s

[kubelet-check] The kubelet is not healthy after 4m0s

Unfortunately, an error has occurred, likely caused by:

  • The kubelet is not running
  • The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)

error execution phase wait-control-plane: failed while waiting for the kubelet to start

At first glance, this error doesn't reveal the actual root cause.


Step 1: Keep the Failed Containers​

By default, Kind removes failed containers, making debugging difficult.

I recreated the cluster using:

kind create cluster --retain --config kind-config.yaml

This preserved the containers after the failure.


Step 2: Inspect the Control Plane Container​

I connected to the control plane node:

docker exec -it <control-plane-container> bash

Then checked the kubelet logs:

journalctl -u kubelet

This immediately showed the real error:

failed to validate kubelet configuration, kubelet is configured to not run on a host using cgroup v1. cgroup v1 support is unsupported and will be removed in a future release.

This was much more useful than the generic kubelet-check error.


Step 3: Verify Docker's cgroup Version​

On the Windows host:

docker info

The relevant output was:

Cgroup Driver: cgroupfs Cgroup Version: 1

That was unexpected.

Modern Kubernetes versions no longer support cgroup v1.


Step 4: Verify the Container Runtime​

To confirm the container itself was also using cgroup v1:

docker run --rm alpine sh -c "mount | grep cgroup"

Output:

cgroup on /sys/fs/cgroup/cpu type cgroup cgroup on /sys/fs/cgroup/memory type cgroup ...

Inside the Kind control plane:

stat -fc %T /sys/fs/cgroup

Output:

tmpfs

This confirmed that the environment was not using a unified cgroup v2 hierarchy.


Root Cause​

The Docker engine was exposing cgroup v1.

Since the Kind node image (kindest/node:v1.35.0) contains a Kubernetes version that no longer supports cgroup v1, the kubelet exited immediately during startup.

As a result:

  • kubelet never started
  • the health endpoint on 127.0.0.1:10248 never became available
  • kubeadm init failed
  • Kind reported only the generic "kubelet is not healthy" error

The Fix​

I added the following configuration to my Windows .wslconfig file:

[wsl2]
kernelCommandLine="cgroup_no_v1=all systemd.unified_cgroup_hierarchy=1"

The file is located at:

C:\Users\<username>\.wslconfig

What those kernel parameters do

  • cgroup_no_v1=all
    • Disables all cgroup v1 controllers.
    • Forces the system to use cgroup v2.
  • systemd.unified_cgroup_hierarchy=1
    • Enables the unified cgroup v2 hierarchy.
    • This is what modern Kubernetes expects.

After saving the file:

  1. Restart WSL
wsl --shutdown
  1. Restart Docker Desktop.

Verify the Fix​

Check the Docker cgroup version:

docker info --format '{{json .CgroupVersion}}'

Output:

"2"

Now create the cluster again:

kind create cluster --config kind-config.yaml

The cluster was created successfully.

Verify the nodes:

kubectl get nodes

Example output:

NAME STATUS ROLES AGE VERSION cka-lab-control-plane Ready control-plane 15m v1.35.0 cka-lab-worker Ready <none> 15m v1.35.0 cka-lab-worker2 Ready <none> 15m v1.35.0

Lessons Learned​

The initial Kind error message pointed only to an unhealthy kubelet, but the actual issue was much deeper.

The investigation process that led to the solution was:

  1. Preserve the failed Kind containers using --retain.
  2. Connect to the control plane container.
  3. Inspect the kubelet logs using journalctl.
  4. Identify the cgroup v1 error.
  5. Verify Docker's cgroup version.
  6. Configure WSL to use a unified cgroup v2 hierarchy.
  7. Restart WSL and Docker Desktop.
  8. Recreate the cluster successfully.

The key takeaway is that journalctl -u kubelet inside the Kind control plane container provides the real reason behind kubelet startup failures, whereas the error displayed by Kind is often only a symptom.


References​