--- title: Adding Windows worker nodes content_type: task weight: 11 --- {{< feature-state for_k8s_version="v1.18" state="beta" >}} This page explains how to add Windows worker nodes to a kubeadm cluster. ## {{% heading "prerequisites" %}} * A running [Windows Server 2022](https://www.microsoft.com/cloud-platform/windows-server-pricing) (or higher) instance with administrative access. * A running kubeadm cluster created by `kubeadm init` and following the steps in the document [Creating a cluster with kubeadm](/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/). ## Adding Windows worker nodes {{< note >}} To facilitate the addition of Windows worker nodes to a cluster, PowerShell scripts from the repository https://sigs.k8s.io/sig-windows-tools are used. {{< /note >}} Do the following for each machine: 1. Open a PowerShell session on the machine. 1. Make sure you are Administrator or a privileged user. Then proceed with the steps outlined below. ### Install containerd {{% thirdparty-content %}} To install containerd, first run the following command: ```PowerShell curl.exe -LO https://raw.githubusercontent.com/kubernetes-sigs/sig-windows-tools/master/hostprocess/Install-Containerd.ps1 `````` Then run the following command, but first replace `CONTAINERD_VERSION` with a recent release from the [containerd repository](https://github.com/containerd/containerd/releases). The version must not have a `v` prefix. For example, use `1.7.22` instead of `v1.7.22`: ```PowerShell .\Install-Containerd.ps1 -ContainerDVersion CONTAINERD_VERSION ``` * Adjust any other parameters for `Install-Containerd.ps1` such as `netAdapterName` as you need them. * Set `skipHypervisorSupportCheck` if your machine does not support Hyper-V and cannot host Hyper-V isolated containers. * If you change the `Install-Containerd.ps1` optional parameters `CNIBinPath` and/or `CNIConfigPath` you will need to configure the installed Windows CNI plugin with matching values. ### Install kubeadm and kubelet Run the following commands to install kubeadm and the kubelet: ```PowerShell curl.exe -LO https://raw.githubusercontent.com/kubernetes-sigs/sig-windows-tools/master/hostprocess/PrepareNode.ps1 .\PrepareNode.ps1 -KubernetesVersion v{{< skew currentVersion >}} ``` * Adjust the parameter `KubernetesVersion` of `PrepareNode.ps1` if needed. ### Run `kubeadm join` Run the command that was output by `kubeadm init`. For example: ```bash kubeadm join --token : --discovery-token-ca-cert-hash sha256: ``` #### Additional information about kubeadm join {{< note >}} To specify an IPv6 tuple for `:`, IPv6 address must be enclosed in square brackets, for example: `[2001:db8::101]:2073`. {{< /note >}} If you do not have the token, you can get it by running the following command on the control plane node: ```bash # Run this on a control plane node sudo kubeadm token list ``` The output is similar to this: ```console TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS 8ewj1p.9r9hcjoqgajrj4gi 23h 2018-06-12T02:51:28Z authentication, The default bootstrap system: signing token generated by bootstrappers: 'kubeadm init'. kubeadm: default-node-token ``` By default, node join tokens expire after 24 hours. If you are joining a node to the cluster after the current token has expired, you can create a new token by running the following command on the control plane node: ```bash # Run this on a control plane node sudo kubeadm token create ``` The output is similar to this: ```console 5didvk.d09sbcov8ph2amjw ``` If you don't have the value of `--discovery-token-ca-cert-hash`, you can get it by running the following commands on the control plane node: ```bash sudo cat /etc/kubernetes/pki/ca.crt | openssl x509 -pubkey | openssl rsa -pubin -outform der 2>/dev/null | \ openssl dgst -sha256 -hex | sed 's/^.* //' ``` The output is similar to: ```console 8cb2de97839780a412b93877f8507ad6c94f73add17d5d7058e91741c9d5ec78 ``` The output of the `kubeadm join` command should look something like: ``` [preflight] Running pre-flight checks ... (log output of join workflow) ... Node join complete: * Certificate signing request sent to control-plane and response received. * Kubelet informed of new secure connection details. Run 'kubectl get nodes' on control-plane to see this machine join. ``` A few seconds later, you should notice this node in the output from `kubectl get nodes`. (for example, run `kubectl` on a control plane node). ### Network configuration CNI setup on clusters mixed with Linux and Windows nodes requires more steps than just running `kubectl apply` on a manifest file. Additionally, the CNI plugin running on control plane nodes must be prepared to support the CNI plugin running on Windows worker nodes. {{% thirdparty-content %}} Only a few CNI plugins currently support Windows. Below you can find individual setup instructions for them: * [Flannel](https://sigs.k8s.io/sig-windows-tools/guides/flannel.md) * [Calico](https://docs.tigera.io/calico/latest/getting-started/kubernetes/windows-calico/) ### Install kubectl for Windows (optional) {#install-kubectl} See [Install and Set Up kubectl on Windows](/docs/tasks/tools/install-kubectl-windows/). ## {{% heading "whatsnext" %}} * See how to [add Linux worker nodes](/docs/tasks/administer-cluster/kubeadm/adding-linux-nodes/).