Deploy a Windows Server container on an Azure Kubernetes Service (AKS) cluster using PowerShell

Azure Kubernetes Service (AKS) is a managed Kubernetes service that lets you quickly deploy and manage clusters. In this article, you use Azure PowerShell to deploy an AKS cluster that runs Windows Server containers. You also deploy an ASP.NET sample application in a Windows Server container to the cluster.

Note

To get started with quickly provisioning an AKS cluster, this article includes steps to deploy a cluster with default settings for evaluation purposes only. Before deploying a production-ready cluster, we recommend that you familiarize yourself with our baseline reference architecture to consider how it aligns with your business requirements.

Before you begin

This quickstart assumes a basic understanding of Kubernetes concepts. For more information, see Kubernetes core concepts for Azure Kubernetes Service (AKS).

Create a resource group

An Azure resource group is a logical group in which Azure resources are deployed and managed. When you create a resource group, you're asked to specify a location. This location is where resource group metadata is stored and where your resources run in Azure if you don't specify another region during resource creation.

To create a resource group, use the New-AzResourceGroup cmdlet. The following example creates a resource group named myResourceGroup in the eastus region.

New-AzResourceGroup -Name myResourceGroup -Location eastus

The following sample output shows that the resource group was created successfully:

ResourceGroupName : myResourceGroup
Location          : eastus
ProvisioningState : Succeeded
Tags              :
ResourceId        : /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup

Create an AKS cluster

In this section, we create an AKS cluster with the following configuration:

  • The cluster is configured with two nodes to ensure it operates reliably. A node is an Azure virtual machine (VM) that runs the Kubernetes node components and container runtime.
  • The -WindowsProfileAdminUserName and -WindowsProfileAdminUserPassword parameters set the administrator credentials for any Windows Server nodes on the cluster and must meet the Windows Server password complexity requirements.
  • The node pool uses VirtualMachineScaleSets.

To create the AKS cluster with Azure PowerShell, follow these steps:

  1. Create the administrator credentials for your Windows Server containers using the following command. This command prompts you to enter a WindowsProfileAdminUserName and WindowsProfileAdminUserPassword. The password must be a minimum of 14 characters and meet the Windows Server password complexity requirements.

    $AdminCreds = Get-Credential `
        -Message 'Please create the administrator credentials for your Windows Server containers'
    
  2. Create your cluster using the New-AzAksCluster cmdlet and specify the WindowsProfileAdminUserName and WindowsProfileAdminUserPassword parameters.

    New-AzAksCluster -ResourceGroupName myResourceGroup `
        -Name myAKSCluster `
        -NodeCount 2 `
        -NetworkPlugin azure `
        -NodeVmSetType VirtualMachineScaleSets `
        -WindowsProfileAdminUserName $AdminCreds.UserName `
        -WindowsProfileAdminUserPassword $secureString `
        -GenerateSshKey
    

    After a few minutes, the command completes and returns JSON-formatted information about the cluster. Occasionally, the cluster can take longer than a few minutes to provision. Allow up to 10 minutes for provisioning.

    If you get a password validation error, and the password that you set meets the length and complexity requirements, try creating your resource group in another region. Then try creating the cluster with the new resource group.

    If you don't specify an administrator username and password when creating the node pool, the username is set to azureuser and the password is set to a random value. For more information, see the Windows Server FAQ.

    The administrator username can't be changed, but you can change the administrator password that your AKS cluster uses for Windows Server nodes using az aks update. For more information, see the Windows Server FAQ.

    To run an AKS cluster that supports node pools for Windows Server containers, your cluster needs to use a network policy that uses [Azure CNI (advanced)][azure-cni] network plugin. The -NetworkPlugin azure parameter specifies Azure CNI.

Add a node pool

By default, an AKS cluster is created with a node pool that can run Linux containers. You must add another node pool that can run Windows Server containers alongside the Linux node pool.

Windows Server 2022 is the default operating system for Kubernetes versions 1.25.0 and higher. Windows Server 2019 is the default OS for earlier versions. If you don't specify a particular OS SKU, Azure creates the new node pool with the default SKU for the version of Kubernetes used by the cluster.

To use the default OS SKU, create the node pool without specifying an OS SKU. The node pool is configured for the default operating system based on the Kubernetes version of the cluster.

Add a Windows Server node pool using the New-AzAksNodePool cmdlet. The following command creates a new node pool named npwin and adds it to myAKSCluster. The command also uses the default subnet in the default virtual network created when running New-AzAksCluster:

New-AzAksNodePool -ResourceGroupName myResourceGroup `
    -ClusterName myAKSCluster `
    -VmSetType VirtualMachineScaleSets `
    -OsType Windows `
    -Name npwin

Connect to the cluster

You use kubectl, the Kubernetes command-line client, to manage your Kubernetes clusters. If you use Azure Cloud Shell, kubectl is already installed. If you want to install kubectl locally, you can use the Install-AzAzAksCliTool cmdlet.

  1. Configure kubectl to connect to your Kubernetes cluster using the Import-AzAksCredential cmdlet. This command downloads credentials and configures the Kubernetes CLI to use them.

    Import-AzAksCredential -ResourceGroupName myResourceGroup -Name myAKSCluster
    
  2. Verify the connection to your cluster using the kubectl get command, which returns a list of the cluster nodes.

    kubectl get nodes
    

    The following sample output shows all the nodes in the cluster. Make sure the status of all nodes is Ready:

    NAME                                STATUS   ROLES   AGE   VERSION
    aks-nodepool1-20786768-vmss000000   Ready    agent   22h   v1.27.7
    aks-nodepool1-20786768-vmss000001   Ready    agent   22h   v1.27.7
    aksnpwin000000                      Ready    agent   21h   v1.27.7
    

Deploy the application

A Kubernetes manifest file defines a desired state for the cluster, such as what container images to run. In this article, you use a manifest to create all objects needed to run the ASP.NET sample application in a Windows Server container. This manifest includes a Kubernetes deployment for the ASP.NET sample application and an external Kubernetes service to access the application from the internet.

The ASP.NET sample application is provided as part of the .NET Framework Samples and runs in a Windows Server container. AKS requires Windows Server containers to be based on images of Windows Server 2019 or greater. The Kubernetes manifest file must also define a node selector to tell your AKS cluster to run your ASP.NET sample application's pod on a node that can run Windows Server containers.

  1. Create a file named sample.yaml and copy in the following YAML definition.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sample
      labels:
        app: sample
    spec:
      replicas: 1
      template:
        metadata:
          name: sample
          labels:
            app: sample
        spec:
          nodeSelector:
            "kubernetes.io/os": windows
          containers:
          - name: sample
            image: mcr.microsoft.com/dotnet/framework/samples:aspnetapp
            resources:
              limits:
                cpu: 1
                memory: 800M
            ports:
              - containerPort: 80
      selector:
        matchLabels:
          app: sample
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: sample
    spec:
      type: LoadBalancer
      ports:
      - protocol: TCP
        port: 80
      selector:
        app: sample
    

    For a breakdown of YAML manifest files, see Deployments and YAML manifests.

    If you create and save the YAML file locally, then you can upload the manifest file to your default directory in CloudShell by selecting the Upload/Download files button and selecting the file from your local file system.

  2. Deploy the application using the kubectl apply command and specify the name of your YAML manifest.

    kubectl apply -f sample.yaml
    

    The following sample output shows the deployment and service created successfully:

    deployment.apps/sample created
    service/sample created
    

Test the application

When the application runs, a Kubernetes service exposes the application front end to the internet. This process can take a few minutes to complete. Occasionally, the service can take longer than a few minutes to provision. Allow up to 10 minutes for provisioning.

  1. Check the status of the deployed pods using the kubectl get pods command. Make all pods are Running before proceeding.

    kubectl get pods
    
  2. Monitor progress using the kubectl get service command with the --watch argument.

    kubectl get service sample --watch
    

    Initially, the output shows the EXTERNAL-IP for the sample service as pending:

    NAME               TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    sample             LoadBalancer   10.0.37.27   <pending>     80:30572/TCP   6s
    

    When the EXTERNAL-IP address changes from pending to an actual public IP address, use CTRL-C to stop the kubectl watch process. The following sample output shows a valid public IP address assigned to the service:

    sample  LoadBalancer   10.0.37.27   52.179.23.131   80:30572/TCP   2m
    
  3. See the sample app in action by opening a web browser to the external IP address of your service.

    Screenshot of browsing to ASP.NET sample application.

Delete resources

If you don't plan on going through the AKS tutorial, then delete your cluster to avoid incurring Azure charges. Call the Remove-AzResourceGroup cmdlet to remove the resource group, container service, and all related resources.

Remove-AzResourceGroup -Name myResourceGroup

Note

The AKS cluster was created with system-assigned managed identity (default identity option used in this quickstart). The Azure platform manages this identity, so it doesn't require removal.

Next steps

In this quickstart, you deployed a Kubernetes cluster and then deployed an ASP.NET sample application in a Windows Server container to it. This sample application is for demo purposes only and doesn't represent all the best practices for Kubernetes applications. For guidance on creating full solutions with AKS for production, see AKS solution guidance.

To learn more about AKS, and to walk through a complete code-to-deployment example, continue to the Kubernetes cluster tutorial.