Kubernetes for Windows How to

Reminder: This article contains Kubernetes term and step. Due to I have been in the Kubernetes world for a long time. So, I might miss some information describing. Please leave your message, I could update this article.

Follow by the Kubernetes for Windows experiences. I would like to share Kubernetes for Windows How to. This article will contains the following topics.


Kubernetes for Windows contains the follow nodes:

Maybe you just need Windows Container only, but we still need Linux OS. There are a lot of Kubernetes components in the Control Plane node. Additionally, the one of magical gMSA service has to be in the Linux node. Therefore, there is no pure Windows infra any more. Even Microsoft, they are keeping embracing Linux (open source). That is why I use Kubernetes for Windows wording, not Windows Kubernetes because of this wording could present more real meaning.

Regarding Kubernetes components introduction, you could refer to the official article (reference 1). In this article, I would like to focus on How the Windows node working.

To ensure Windows node working, Windows node requires the kubelet, kube-proxy components and a network add-on (reference 2).

kubelet. kubelet is running as Windows service in the each Windows node. People could leverage the following PowerShell command to get the status of kubelet service. According to official article, The kubelet takes a set of PodSpecs that are provided through various mechanisms and ensures that the containers described in those PodSpecs are running and healthy.

get-service kubelet

kube-proxy. In the version 1.14, kube-proxy is running as Windows service in each Windows node such as kubelet. Since 1.16, kube-proxy is runing as Pod. It is more easy to implement it now. That is to say, once kubelet service got problem, kube-proxy won’t work.

In the official article. kube-proxy maintains network rules on nodes. These network rules allow network communication to your Pods from network sessions inside or outside of your cluster

Network add-on. kube-proxy maintains the network rules. However, we still need network add-on to implement cross node pod. Currently, I use flannel network add-on for on-premise cluster. For the cloud cluster, I would suggest leverage Cloud provider solution.


For the Windows node installation, there are two topics.

Cloud provider Kubernetes for Windows

Although I have KOps Cluster (a AWS Kubernetes solution), but I only implemented Windows node in EKS. Once I tried KOps for windows. I will publish another How to article.

Back to the EKS for Windows, I would say it is more easy then on-premise cluser. I strongly suggest to leverage eksctl (EKS cli) to create Windows nodegroup. In the past, I tried CloudFormation in version 1.14. I would say that is nightmare. Additionally, if you will use gMSA, that will be more difficult. You will need to implement auto-join AD domain for Windows node AutoScalling. Regarding gMSA, I will introduce it in “gMSA for your Windows Container”. For the Windows node installation, the steps as the following.

eksctl create nodegroup \
--cluster=$CLUST_NAME \
--name $NODE_NAME \
--node-ami-family WindowsServer2019CoreContainer \
--node-type=t3.large \
--nodes-min=1 \
--nodes-max=1 \
--node-private-networking \
--ssh-public-key=$SSHKEY \
--node-volume-size=100 \
--asg-access \
--external-dns-access \
--full-ecr-access \
eksctl utils install-vpc-controllers --name=$CLUST_NAME --approve
aws eks  — region $YOUR_REGION update-kubeconfig  — name $CLUST_NAME
kubectl get nodes

On-premise Kubernetes for Windows

On-premise Cluster installation is more difficult then Cloud Cluster. If you need to build multiple Control Plan, that will be more difficult. Futhermore, If your cluster behind of proxy, that will be more and more difficult for implementation. Regarding Kubernetes installation, I will publish it in the future. For now, I list the following check items for Control Plane and Linux node.

Docker service

Control Plane (google search the following action, or reference 3)

kubeadm init --pod-network-cidr= --service-cidr= --kubernetes-version=1.18.6
kubectl apply -f kube-flannel.yml

Linux node. Once Control Plan ready, you could proceed install Linux node.

kubeadm token create --print-join-command
kubeadm join {API SERVER} --token XXXXXXXXXXXXXXXX --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxx

Docker for Windows. Once Control Plane and Linux node ready. We could install Windows node now.

Windows node. I strongly recommend to use Windows Service Core.

netsh firewall set opmode mode=disable
docker pull sigwindowstools/kube-proxy:v1.18.6
docker pull sigwindowstools/flannel:0.12.0
docker pull mcr.microsoft.com/windows/nanoserver:1809
docker tag mcr.microsoft.com/windows/nanoserver:1809 microsoft/nanoserver:latest
docker run microsoft/nanoserver:latest
docker pull mcr.microsoft.com/k8s/core/pause:1.2.0
kubectl apply -f kube-flannel-overlay.yml
kubectl apply -f kube-proxy-win.yml
Install-WindowsFeature RSAT-AD-PowerShell
Install-Module -Name CredentialSpec
Rename-NetAdapter "Ethernet0" -NewName Ethernet -ErrorAction SilentlyContinue
Get-NetAdapter | ? {$_.name -ne "Ethernet"} | Disable-NetAdapter
mkdir c:\k
kubeadm token create --print-join-command
powershell -command "if((docker network ls) -match 'host                nat'){$null}else{docker network create -d nat host}"
kubectl get nodes


Before verify your Windows node, you have to install kubectl in your Computer or bastion server. Furthermore, you have to copy content of kubeconfig to your computer ~/.kube/config. I recommend people to use Kubernetes Lenapp. It is really easy to maintain your Clusters or Namespaces. It supports Windows Desktop, MacOS, Linux Desktop.

Once Windows node ready, it is time to deploy a simple Web Pod.

kubectl apply -f aspnet.yaml
# get pods
kubectl get pods
# output
aspnet-56887957d-4m5xg 0/1 ContainerCreating 0 10m
# describe pods
kubectl describe pods aspnet-56887957d-4m5xg
# output
Name: aspnet-56887957d-4m5xg
Namespace: default
Priority: 0
Node: <Windows NODE NAME>
Start Time: Sat, 28 Nov 2020 11:43:56 +0800
Labels: app=aspnet
Annotations: <none>
Status: Pending
Controlled By: ReplicaSet/aspnet-56887957d
Container ID:
Image: mcr.microsoft.com/dotnet/framework/aspnet:4.8
Image ID:
Port: 80/TCP
Host Port: 0/TCP
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment: <none>
/var/run/secrets/kubernetes.io/serviceaccount from default-token-72dc8 (ro)
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Type: Secret (a volume populated by a Secret)
SecretName: default-token-72dc8
Optional: false
QoS Class: BestEffort
Node-Selectors: beta.kubernetes.io/os=windows
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/aspnet-56887957d-4m5xg to xx-xxx-xxxxxx
Normal Pulling 10m kubelet, xx-xxx-xxxxxx Pulling image "mcr.microsoft.com/dotnet/framework/aspnet:4.8"
# get pods
kubectl get pods
# output
aspnet-56887957d-4m5xg 1/1 Running 0 15m
# get servicekubectl get service# outputNAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
aspnet NodePort <none> 80:31114/TCP 19m

Experience of How to

When version 1.14, it was really difficult to implement Windows node. Now, we can easily add Windows node by kubeadm join such as Linux node. I believe there is a lot of people effort.

Once your Windows node ready. The next challenge will be Windows application deployment and centralize Log. Regarding Windows Application How to, I will share it in Kubernetes for Windows Application.

Maybe someone might ask that Do we really need Windows node? I think this question should be answered by you. For me, I have hybrid mode because of Windows node still have something good, e.g. gMSA. For now, I just shared what I learned and what I experienced.




Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store