Deploying a Windows Server application

In this article, you learn how to deploy a Windows Server Pod.

Deploying a Windows Server application to a standard cluster

The following four steps guide you through deploying your Windows application.

Step 1: Create a cluster

Create a cluster using Windows Server node pools.

Step 2: Create a Deployment file

To ensure your Pods are correctly scheduled onto Windows Server nodes, you must add a node selector to your Pod specification:

nodeSelector:
   kubernetes.io/os: windows

The following example Deployment file (iis.yaml), deploys Microsoft's official IIS image to a single Pod:

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

Step 3: Create the Deployment and expose it with a service

Create and expose the Deployment file you created above as a Kubernetes Service with an external load balancer Deployment.

  1. To create the Deployment, run:

    kubectl apply -f iis.yaml`
    
  2. To expose the Deployment, run:

    kubectl expose deployment iis \
    --type=LoadBalancer \
    --name=iis
    

Step 4: Verify the Pod is running

Make sure the Pod is functioning by validating it.

  1. Check the status of the Pod using kubectl.

    kubectl get pods
    
  2. Wait until the returned output shows that the Pod has Running as its status.

    NAME                   READY     STATUS    RESTARTS   AGE
    iis-5c997657fb-w95dl   1/1       Running   0          28s
    
  3. Get the status of the service, and wait until the external IP field is populated.

    kubectl get service iis
    

    You should see the following output:

    NAME   TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)        AGE
    iis    LoadBalancer   10.44.2.112   [EXTERNAL_IP]    80:32233/TCP   17s
    

    Now you can use your browser to open http://[EXTERNAL_IP] to see the IIS web page.

Deploying a Windows Server container application to a private cluster

This section shows you how to deploy a Windows Server container application to a private cluster.

Windows Server container images have several layers and the base layers are provided by Microsoft. The base layers are stored as a foreign layer instead of being embedded with the image as Linux Docker image layers are. When a Windows Server container image is pulled for the first time, the base layers must typically be downloaded from Microsoft servers. Because private cluster nodes don't have connectivity to the internet, the Windows Server base container layers cannot be pulled from Microsoft servers directly.

To use private clusters, you can configure the Docker daemon to allow pushing non-distributable layers to private registries. To learn more, see Considerations for air-gapped registries on Docker's GitHub page.

There are four step to doing this:

  1. Create a private cluster with Windows Server nodes.
  2. Build the Windows Server application Docker image.
  3. Deploy the application to a private cluster.
  4. Verify that the Pod is running.

Step 1: Create a private cluster

Follow the instructions in Creating a cluster with Windows Server nodes and Creating a private cluster to create and add a Windows node pool to a private cluster.

Step 2: Create a Windows Server application image for use with private clusters.

  1. To build the Docker image,start a Compute Engine instance with the Windows Server version you want to run your application containers on, such as Windows Server 2019 or Windows Server version 1909, and ensure you have internet connectivity.
  2. In the Compute instance, navigate to the Docker daemon config:

    PS C:\> cat C:\ProgramData\docker\config\daemon.json
    
  3. Configure the Docker daemon.json file to allow foreign layers to be pushed to your private registry:

    {
    "allow-nondistributable-artifacts": ["gcr.io"]
    }
    

    gcr.io refers to Google Container Registry, where the image will be hosted.

  4. Restart the Docker daemon:

    PS C:> Restart-Service docker
    

  5. Build and tag the Docker image for your application:

    PS C:> cd C:\my-app
    PS C:\my-app> docker build -t gcr.io/my-project/my-app:v2
    

    This command instructs Docker to build the image using the Dockerfile in the current directory and tag it with a name, such as gcr.io/my-project/my-app:v2.

  6. Push the application's Docker image to the gcr.io registry in my-project. With the allow-nondistributable-artifacts configuration set, this should cause the Windows base layers to be pushed to your private registry.

    PS C:\my-app> docker push gcr.io/my-project/my-app:v2
    

Step 3: Create the Deployment

A sample deployment called my-app.yaml is given below. The image in this example is the one you pushed in step 2 (gcr.io/my-project/my-app:v2).

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      nodeSelector:
       kubernetes.io/os: Windows
      tolerations:
      - effect: NoSchedule
        key: node.kubernetes.io/os
        operator: Equal
        value: windows
      containers:
      - name: my-server
        image: gcr.io/my-project/my-app:v2

To deploy this application to your private cluster:

gcloud container clusters get-credentials [PRIVATE-CLUSTER]
kubectl apply -f my-app.yaml

Where [PRIVATE-CLUSTER] is the name of cluster you created in step 1.

Step 4: Verify the Pod is running

List all Pods to ensure it is running correctly.

kubectl get pods

The expected result should show the Pod with a status of Running.

NAME                     READY   STATUS    RESTARTS   AGE
my-app-c95fc5596-c9zcb   1/1     Running   0          5m