Purpose: For platform engineers, shows how to add a Windows worker node to an existing openCenter Kubernetes cluster, covering collection installation through a verified running node.
Outcome
By the end of this tutorial you will have a Windows Server node running as a Kubernetes worker in your cluster, with ContainerD as the container runtime and kubelet registered as a Windows service.
Prerequisites
-
An existing openCenter Kubernetes cluster with at least one Linux control plane node
-
A Windows Server 2019 or 2022 machine with SSH enabled (OpenSSH Server feature)
-
Ansible 2.14+ installed on your workstation with the
ansible.windowscollection -
SSH or WinRM connectivity from your workstation to the Windows node
-
Administrator credentials for the Windows node
-
Network connectivity between the Windows node and the control plane (port 6443 for API server, port 10250 for kubelet)
Step 1: Install the collection
Install the Ansible collection from the repository:
ansible-galaxy collection install opencenter-cloud.opencenter_windows_workers
Verify the installation:
ansible-galaxy collection list | grep opencenter_windows
You should see opencenter-cloud.opencenter_windows_workers 0.0.1 in the output.
Step 2: Create your inventory
Create a file called inventory.ini with your control plane and Windows node details:
[oc_controlplane_nodes]
control-plane-01 ansible_host=192.168.1.10
[windows_workers]
win-worker-01 ansible_host=192.168.1.101
[windows_workers:vars]
ansible_connection=ssh
ansible_shell_type=powershell
ansible_user=Administrator
Replace the IP addresses with your actual node addresses. The oc_controlplane_nodes group is required because the win-kubeadm role delegates to the first control plane node to generate a join token.
Step 3: Create the playbook
Create a file called windows-workers.yml:
---
- name: Setup Windows Kubernetes Worker
hosts: windows_workers
vars:
containerd_version: "1.7.13"
crictl_version: "1.29.0"
kube_version: "1.29.0"
k8s_internal_ip: "192.168.1.10"
roles:
- opencenter-cloud.opencenter_windows_workers.win-containerd
- opencenter-cloud.opencenter_windows_workers.win-kubeadm
Set kube_version to match your cluster’s Kubernetes version. Set k8s_internal_ip to your control plane’s internal IP (or load balancer IP if using HA).
Step 4: Run the playbook
ansible-playbook -i inventory.ini windows-workers.yml
The playbook will:
-
Check for pending reboots and handle them
-
Install Windows features (Containers, Hyper-V) — this triggers a reboot
-
Download and install ContainerD, register it as a service
-
Install crictl for container runtime debugging
-
Download kubelet and kubeadm binaries
-
Install NSSM and configure kubelet as a Windows service
-
Install RemoteAccess features for BGP routing (Calico compatibility)
-
Retrieve a join token from the control plane
-
Execute
kubeadm joinon the Windows node
Expect 1–2 reboots during execution. The playbook handles them automatically.
Check your work
From a machine with kubectl access to the cluster:
kubectl get nodes -o wide
You should see your Windows node listed with status Ready (it may take a minute after the join completes). The OS-IMAGE column will show Windows Server.
Verify the kubelet service is running on the Windows node:
Get-Service kubelet | Select-Object Name, Status, StartType
Expected output:
Name Status StartType
---- ------ ---------
kubelet Running Automatic
Check that ContainerD is also running:
Get-Service containerd | Select-Object Name, Status, StartType
Next steps
-
Apply a CNI DaemonSet for Windows (Calico or Flannel) — the BGP routing features are already installed
-
Apply kube-proxy configuration for Windows
-
Deploy a test Windows container workload to confirm scheduling works
-
Read the ../reference/win-containerd-role.md[win-containerd role reference] and ../reference/win-kubeadm-role.md[win-kubeadm role reference] for all available configuration options