The Kubernetes platform can now be used to run both Linux and Windows containers. This page shows how one or more Windows nodes can be registered to a cluster.
Obtain a Windows Server 2019 license (or higher) in order to configure the Windows node that hosts Windows containers. You can use your organization’s licenses for the cluster, or acquire one from Microsoft, a reseller, or via the major cloud providers such as GCP, AWS, and Azure by provisioning a virtual machine running Windows Server through their marketplaces. A time-limited trial is also available.
Build a Linux-based Kubernetes cluster in which you have access to the control-plane (some examples include Creating a single control-plane cluster with kubeadm, AKS Engine, GCE, AWS.
Kubernetes cluster management requires careful planning of your IP addresses so that you do not inadvertently cause network collision. This guide assumes that you are familiar with the Kubernetes networking concepts.
In order to deploy your cluster you need the following address spaces:
Subnet / address range | Description | Default value |
---|---|---|
Service Subnet | A non-routable, purely virtual subnet that is used by pods to uniformly access services without caring about the network topology. It is translated to/from routable address space by kube-proxy running on the nodes. | 10.96.0.0/12 |
Cluster Subnet | This is a global subnet that is used by all pods in the cluster. Each node is assigned a smaller /24 subnet from this for their pods to use. It must be large enough to accommodate all pods used in your cluster. To calculate minimumsubnet size: (number of nodes) + (number of nodes * maximum pods per node that you configure) . Example: for a 5 node cluster for 100 pods per node: (5) + (5 * 100) = 505. | 10.244.0.0/16 |
Kubernetes DNS Service IP | IP address of kube-dns service that is used for DNS resolution & cluster service discovery. | 10.96.0.10 |
Review the networking options supported in ‘Intro to Windows containers in Kubernetes: Supported Functionality: Networking’ to determine how you need to allocate IP addresses for your cluster.
While the Kubernetes control-plane runs on your Linux node(s), the following components are configured and run on your Windows node(s).
Get the latest binaries from https://github.com/kubernetes/kubernetes/releases, starting with v1.14 or later. The Windows-amd64 binaries for kubeadm, kubectl, kubelet, and kube-proxy can be found under the CHANGELOG link.
Once you have a Linux-based Kubernetes control-plane (“Master”) node you are ready to choose a networking solution. This guide illustrates using Flannel in VXLAN mode for simplicity.
Prepare Kubernetes master for Flannel
Some minor preparation is recommended on the Kubernetes master in our cluster. It is recommended to enable bridged IPv4 traffic to iptables chains when using Flannel. This can be done using the following command:
sudo sysctl net.bridge.bridge-nf-call-iptables=1
Download & configure Flannel
Download the most recent Flannel manifest:
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
There are two sections you should modify to enable the vxlan networking backend:
After applying the steps below, the net-conf.json
section of kube-flannel.yml
should look as follows:
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan",
"VNI" : 4096,
"Port": 4789
}
}
Note: The VNI must be set to 4096 and port 4789 for Flannel on Linux to interoperate with Flannel on Windows. Support for other VNIs is coming soon. See the VXLAN documentation for an explanation of these fields.
In the net-conf.json
section of your kube-flannel.yml
, double-check:
cni-conf.json
section of your kube-flannel.yml
, change the network name to vxlan0
.Your cni-conf.json
should look as follows:
cni-conf.json: |
{
"name": "vxlan0",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
Apply the Flannel manifest and validate
Let’s apply the Flannel configuration:
kubectl apply -f kube-flannel.yml
Next, since the Flannel pods are Linux-based, apply a NodeSelector patch, which can be found here, to the Flannel DaemonSet pod:
kubectl patch ds/kube-flannel-ds-amd64 --patch "$(cat node-selector-patch.yml)" -n=kube-system
After a few minutes, you should see all the pods as running if the Flannel pod network was deployed.
kubectl get pods --all-namespaces
The output looks like as follows:
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-flannel-master 1/1 Running 0 1m
kube-system kube-apiserver-flannel-master 1/1 Running 0 1m
kube-system kube-controller-manager-flannel-master 1/1 Running 0 1m
kube-system kube-dns-86f4d74b45-hcx8x 3/3 Running 0 12m
kube-system kube-flannel-ds-54954 1/1 Running 0 1m
kube-system kube-proxy-Zjlxz 1/1 Running 0 1m
kube-system kube-scheduler-flannel-master 1/1 Running 0 1m
Verify that the Flannel DaemonSet has the NodeSelector applied.
kubectl get ds -n kube-system
The output looks like as follows. The NodeSelector beta.kubernetes.io/os=linux
is applied.
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-flannel-ds 2 2 2 2 2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux 21d
kube-proxy 2 2 2 2 2 beta.kubernetes.io/os=linux 26d
In this section we’ll cover configuring a Windows node from scratch to join a cluster on-prem. If your cluster is on a cloud you’ll likely want to follow the cloud specific guides in the public cloud providers section.
Note: All code snippets in Windows sections are to be run in a PowerShell environment with elevated permissions (Administrator) on the Windows worker node.
Download the SIG Windows tools repository containing install and join scripts
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Start-BitsTransfer https://github.com/kubernetes-sigs/sig-windows-tools/archive/master.zip
tar -xvf .\master.zip --strip-components 3 sig-windows-tools-master/kubeadm/v1.15.0/*
Remove-Item .\master.zip
Customize the Kubernetes configuration file
{
"Cri" : { // Contains values for container runtime and base container setup
"Name" : "dockerd", // Container runtime name
"Images" : {
"Pause" : "mcr.microsoft.com/k8s/core/pause:1.2.0", // Infrastructure container image
"Nanoserver" : "mcr.microsoft.com/windows/nanoserver:1809", // Base Nanoserver container image
"ServerCore" : "mcr.microsoft.com/windows/servercore:ltsc2019" // Base ServerCore container image
}
},
"Cni" : { // Contains values for networking executables
"Name" : "flannel", // Name of network fabric
"Source" : [{ // Contains array of objects containing values for network daemon(s)
"Name" : "flanneld", // Name of network daemon
"Url" : "https://github.com/coreos/flannel/releases/download/v0.11.0/flanneld.exe" // Direct URL pointing to network daemon executable
}
],
"Plugin" : { // Contains values for CNI network plugin
"Name": "vxlan" // Backend network mechanism to use: ["vxlan" | "bridge"]
},
"InterfaceName" : "Ethernet" // Designated network interface name on Windows node to use as container network
},
"Kubernetes" : { // Contains values for Kubernetes node binaries
"Source" : { // Contains values for Kubernetes node binaries
"Release" : "1.15.0", // Version of Kubernetes node binaries
"Url" : "https://dl.k8s.io/v1.15.0/kubernetes-node-windows-amd64.tar.gz" // Direct URL pointing to Kubernetes node binaries tarball
},
"ControlPlane" : { // Contains values associated with Kubernetes control-plane ("Master") node
"IpAddress" : "kubemasterIP", // IP address of control-plane ("Master") node
"Username" : "localadmin", // Username on control-plane ("Master") node with remote SSH access
"KubeadmToken" : "token", // Kubeadm bootstrap token
"KubeadmCAHash" : "discovery-token-ca-cert-hash" // Kubeadm CA key hash
},
"KubeProxy" : { // Contains values for Kubernetes network proxy configuration
"Gates" : "WinOverlay=true" // Comma-separated key-value pairs passed to kube-proxy feature gate flag
},
"Network" : { // Contains values for IP ranges in CIDR notation for Kubernetes networking
"ServiceCidr" : "10.96.0.0/12", // Service IP subnet used by Services in CIDR notation
"ClusterCidr" : "10.244.0.0/16" // Cluster IP subnet used by Pods in CIDR notation
}
},
"Install" : { // Contains values and configurations for Windows node installation
"Destination" : "C:\\ProgramData\\Kubernetes" // Absolute DOS path where Kubernetes will be installed on the Windows node
}
}
Note: Users can generate values for theControlPlane.KubeadmToken
andControlPlane.KubeadmCAHash
fields by runningkubeadm token create --print-join-command
on the Kubernetes control-plane (“Master”) node.
Use the previously downloaded KubeCluster.ps1 script to install Kubernetes on the Windows Server container host:
.\KubeCluster.ps1 -ConfigFile .\Kubeclustervxlan.json -install
where -ConfigFile
points to the path of the Kubernetes configuration file.
Note: In the example below, we are using overlay networking mode. This requires Windows Server version 2019 with KB4489899 and at least Kubernetes v1.14 or above. Users that cannot meet this requirement must useL2bridge
networking instead by selectingbridge
as the plugin in the configuration file.
On the Windows node you target, this step will:
$PATH
environment variable(Optionally) Generate a new SSH key which is required to connect to the control-plane (“Master”) node during joining
Note: For the SSH key generation step, you also need to add the generated public SSH key to theauthorized_keys
file on your (Linux) control-plane node. You only need to do this once. The script prints out the steps you can follow to do this, at the end of its output.
Once installation is complete, any of the generated configuration files or binaries can be modified before joining the Windows node.
This section covers how to join a Windows node with Kubernetes installed with an existing (Linux) control-plane, to form a cluster.
Use the previously downloaded KubeCluster.ps1 script to join the Windows node to the cluster:
.\KubeCluster.ps1 -ConfigFile .\Kubeclustervxlan.json -join
where -ConfigFile
points to the path of the Kubernetes configuration file.
Note: Should the script fail during the bootstrap or joining procedure for whatever reason, start a new PowerShell session before starting each consecutive join attempt.
This step will perform the following actions:
Note: This may cause a network blip for a few seconds while the vSwitch is being created.
Now you can view the Windows nodes in your cluster by running the following:
kubectl get nodes
In this section we’ll cover how to remove a Windows node from a Kubernetes cluster.
Use the previously downloaded KubeCluster.ps1 script to remove the Windows node from the cluster:
.\KubeCluster.ps1 -ConfigFile .\Kubeclustervxlan.json -reset
where -ConfigFile
points to the path of the Kubernetes configuration file.
This step will perform the following actions on the targeted Windows node:
AKS-Engine can deploy a complete, customizable Kubernetes cluster with both Linux & Windows nodes. There is a step-by-step walkthrough available in the docs on GitHub.
Users can easily deploy a complete Kubernetes cluster on GCE following this step-by-step walkthrough on GitHub
Kubeadm is becoming the de facto standard for users to deploy a Kubernetes cluster. Windows node support in kubeadm is an alpha feature since Kubernetes release v1.16. We are also making investments in cluster API to ensure Windows nodes are properly provisioned. For more details, please consult the kubeadm for Windows KEP.
Now that you’ve configured a Windows worker in your cluster to run Windows containers you may want to add one or more Linux nodes as well to run Linux containers. You are now ready to schedule Windows containers on your cluster.
Was this page helpful?
Thanks for the feedback. If you have a specific, answerable question about how to use Kubernetes, ask it on Stack Overflow. Open an issue in the GitHub repo if you want to report a problem or suggest an improvement.