Windows Server containers on Azure Kubernetes Service (AKS) are a bit of a unicorn, but they’re totally achievable. The most surprising thing is that AKS doesn’t natively run Windows nodes; you have to explicitly add a Windows node pool to your existing Linux-based AKS cluster.

Let’s see it in action. Imagine you have a Linux AKS cluster already. You can add a Windows node pool like this:

az aks nodepool add \
  --resource-group myResourceGroup \
  --cluster-name myAKSCluster \
  --name winpool \
  --node-count 1 \
  --os-type Windows \
  --kubernetes-version 1.28.5 \
  --node-vm-size Standard_D4s_v3

This command creates a new node pool named winpool with one Standard_D4s_v3 VM, running Windows Server 2019 (the default for Windows on AKS) and Kubernetes version 1.28.5. Your existing Linux nodes remain untouched.

Now, to deploy a Windows container, you need to tell Kubernetes to schedule it onto one of your Windows nodes. You do this using node selectors in your Deployment YAML:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: iis-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: iis
  template:
    metadata:
      labels:
        app: iis
    spec:
      containers:
      - name: iis
        image: mcr.microsoft.com/windows/servercore:ltsc2022
        ports:
        - containerPort: 80
      nodeSelector:
        kubernetes.io/os: windows

The nodeSelector: kubernetes.io/os: windows is the key. AKS automatically labels Windows nodes with kubernetes.io/os: windows and Linux nodes with kubernetes.io/os: linux. This ensures your Windows container, like the IIS image here, lands on a Windows node. You can verify this by running kubectl get nodes -L kubernetes.io/os.

The problem this solves is the need to modernize legacy Windows applications without a full re-architecture. Many .NET Framework applications, for instance, can be containerized and run on AKS, allowing you to leverage Kubernetes for orchestration, scaling, and management of these applications alongside your cloud-native microservices.

Internally, AKS manages the Windows node pools by provisioning Azure Virtual Machines running a specific Windows Server image that has the necessary container runtime (like containerd) and Kubernetes components pre-installed. The AKS control plane then registers these Windows nodes and can schedule Windows pods onto them. You don’t need to manage the underlying Windows Server OS or the Kubernetes agent on those nodes; AKS handles that for you.

The exact levers you control are the VM size (--node-vm-size), the OS version (e.g., Windows2019 or Windows2022 when adding the nodepool), the Kubernetes version, and the number of nodes in the pool. You can also configure autoscaling for your Windows node pools just like you would for Linux.

A common gotcha is that Windows containers are significantly larger than Linux containers, and startup times can be much longer. This is because the Windows Server Core or Nano Server images themselves are much larger than typical Linux base images, and the container runtime has more overhead. For applications sensitive to startup latency, you might need to provision larger VMs or explore pre-warming strategies.

The next concept to explore is running mixed Windows and Linux workloads within the same Kubernetes cluster, managing their distinct resource requirements and network policies.

Want structured learning?

Take the full Aks course →