Last verified against: Kairos v3.6.0+, CAPI v1.13.3, provider v0.1.0-beta.1.
This guide walks you through creating a single-node k0s cluster on Kairos using Cluster API with the Docker provider (CAPD).
Note: The CAPD sample uses k0s. For k3s clusters, use CAPV or CAPK.
Note: CAPD is a development-only infrastructure provider. Docker-based Kairos clusters do not represent a production topology.
Note on controlPlaneEndpoint: the sample manifest requires Cluster.spec.controlPlaneEndpoint to be set to a reachable host and port before applying. CAPD (like CAPV) does not auto-provision an endpoint; you must supply one. For local kind-based management clusters the Docker container's IP or a host port mapping is the typical choice. Without a valid endpoint, KairosControlPlane stalls with Available=False(WaitingForInfrastructureControlPlaneEndpoint).
- Management Cluster: A Kubernetes cluster (kind, minikube, or any Kubernetes cluster).
- Cluster API: CAPI v1.13.3+ installed (v1beta2 contract).
- CAPD: Cluster API Provider Docker installed.
- Kairos CAPI Provider: Installed (see Install guide).
Install CAPI and CAPD using your preferred method. See the Cluster API book for details.
Recommended (released artifact):
kubectl apply -f https://github.com/kairos-io/cluster-api-provider-kairos/releases/download/v0.1.0-beta.1/kairos-capi-provider.yamlDeveloper install (from source):
make docker-build
make deploySee INSTALL.md for the full developer install process, including the kustomize-CRD note for re-installs.
kubectl create secret generic kairos-user-password \
--from-literal=password=$(openssl rand -base64 32)The sample manifest references this Secret via userPasswordSecretRef. Do not use userPassword inline for anything beyond throwaway local testing.
The sample manifest is at config/samples/capd/kairos_cluster_k0s_single_node.yaml.
Key components:
Secret— user password (referenced byuserPasswordSecretRefin KairosConfigTemplate).Cluster— referencesDockerClusterandKairosControlPlane.DockerCluster— Docker infrastructure cluster.KairosControlPlane— control plane withreplicas: 1(this guide is single-node). HA (replicas: 3/5) is supported on CAPK, CAPV, and CAPM3 — see the README HA section. CAPD is dev-only and HA is not exercised on it; there is no CAPD HA sample.DockerMachineTemplate— template for Docker machines.KairosConfigTemplate— bootstrap configuration withuserPasswordSecretRef.
kubectl apply -f config/samples/capd/kairos_cluster_k0s_single_node.yaml# Watch cluster status
kubectl get cluster kairos-cluster -w
# Check control plane status
kubectl get kairoscontrolplane kairos-control-plane
# Check machines
kubectl get machineskubectl get secret kairos-cluster-kubeconfig \
-o jsonpath='{.data.value}' | base64 -d > kairos-kubeconfig.yaml
kubectl --kubeconfig=kairos-kubeconfig.yaml get nodes
kubectl --kubeconfig=kairos-kubeconfig.yaml get pods -n kube-systemkubectl describe cluster kairos-cluster
kubectl describe kairoscontrolplane kairos-control-plane
kubectl describe machine <machine-name>
kubectl describe kairosconfig <kairosconfig-name>kubectl logs -n kairos-capi-system deployment/kairos-capi-controller-manager
kubectl get kairosconfig -o yamlIf KairosConfig.status.failureMessage is set, the last reconcile failed. The message clears automatically when the underlying condition is resolved (for example, if a missing Secret is created). This is a transient failure, not a terminal one.
If failureMessage contains "secret not found" for kairos-user-password, create the Secret:
kubectl create secret generic kairos-user-password \
--from-literal=password=$(openssl rand -base64 32)The controller retries automatically.
For worker nodes, ensure workerTokenSecretRef references an existing Secret containing the correct key (default: token). Retrieve a k0s worker token from the control plane:
kubectl get secret kairos-cluster-kubeconfig \
-o jsonpath='{.data.value}' | base64 -d > kairos-kubeconfig.yaml
kubectl --kubeconfig=kairos-kubeconfig.yaml exec -n kube-system \
$(kubectl --kubeconfig=kairos-kubeconfig.yaml get pods -n kube-system \
-l app=k0s-controller -o jsonpath='{.items[0].metadata.name}') \
-- k0s token create --role=workerOnce your control plane is ready, apply the workers sample:
kubectl apply -f config/samples/capd/kairos_cluster_k0s_with_workers.yamlThis adds a MachineDeployment for worker nodes referencing a separate KairosConfigTemplate that also uses userPasswordSecretRef. The kairos-worker-token Secret referenced in that template must be created first.
- Configure additional Kubernetes manifests via
spec.manifestsinKairosConfigTemplate. - Scale worker nodes by updating
MachineDeployment.spec.replicas. - HA control planes (
replicas: 3/5) are supported on CAPK, CAPV, and CAPM3 — see the README HA section. CAPD is dev-only; HA is not exercised on it.
kubectl delete -f config/samples/capd/kairos_cluster_k0s_single_node.yaml