Containers & Kubernetes

How to deploy a Windows container on Google Kubernetes Engine

Many people who run Windows containers want to use a container management platform like Kubernetes for resiliency and scalability. In a previous post, we showed you how to run an IIS site inside a Windows container deployed to Windows Server 2019 running on Compute Engine. That’s a good start, but you can now also run Windows containers on Google Kubernetes Engine (GKE). 

Support for Windows containers in Kubernetes was announced earlier in the year with version 1.14, followed by GKE announcement on the same. You can sign up for early access and start testing out Windows containers on GKE. 

In this blog post, let’s look at how to deploy that same Windows container to GKE. 

1. Push your container image to Container Registry

In the previous post, we created a container image locally. The first step is to push that image to Container Registry, so that you can later use it in your Kubernetes deployment.  

To push images from a Windows VM to Container Registry, you need to:

  1. Ensure that the Container Registry API is enabled in your project.
  2. Configure Docker to point to Container Registry. This is explained in more detail here but it is usually done via the gcloud auth configure-docker command.
  3. Make sure that the VM has storage read/write access scope (storage-rw), as explained here

Once you have the right setup, it’s just a regular Docker push:

  C:>docker push
The push refers to repository []
4d8626c6a788: Pushed
8bd5cd9c33e0: Pushed
df246b0408a9: Pushed
fda45f6f282a: Pushed
f3f872f1087c: Pushed
7626b1fc1993: Pushed
fac2806747d6: Skipped foreign layer
c4d02418787d: Skipped foreign layer
latest: digest: sha256:2153656a3c4affefbe9973b79fe45cc35742c7495d6f4b1a689b5d9927dc92cb size: 2201

2. Create a Kubernetes cluster with Windows nodes

Creating a Kubernetes cluster in GKE with Windows nodes happens in two steps:

  1. Create a GKE cluster with version 1.14 or higher, with IP alias enabled and one Linux node.

  2. Add a Windows node pool to the GKE cluster.

Here’s the command to create a GKE cluster with one Linux node and IP aliasing:

  > gcloud container clusters create windows-cluster --cluster-version=1.14 --enable-ip-alias --num-nodes=1

Once you have the basic GKE cluster, you can go ahead and add a Windows pool for Windows nodes to it:

  > gcloud container node-pools create windows-pool --cluster=windows-cluster --image-type=WINDOWS_SAC --no-enable-autoupgrade --machine-type=n1-standard-2

Windows containers are resource intensive, so we chose n1-standard-2 as machine type. We’re also disabling automatic node upgrades. Windows container versions need to be compatible with the node OS version. To avoid unexpected workload disruption, it is recommended that you disable node auto-upgrade for Windows node pools. 

For Windows Server containers in GKE, you’re already licensed for underlying Windows host VMs—containers need no additional licensing.

Now, your GKE cluster is ready and contains one Linux node and three Windows nodes:

GKE cluster.png

3. Run your Windows container as a pod on GKE

Now you’re ready to run your Windows container as a pod on GKE. Create an iis-site-windows.yaml file to describe your Kubernetes deployment:

  apiVersion: apps/v1
kind: Deployment
  name: iis-site-windows
    app: iis-site-windows
  replicas: 2
      app: iis-site-windows
        app: iis-site-windows
      nodeSelector: windows
      - name: iis-site-windows
        - containerPort: 80

Note that you’re creating two pods with the image you pushed earlier to Container Registry. You’re also making sure that the pods are scheduled onto Windows nodes with the nodeSelector tag. 

Create the deployment:

  > kubectl apply -f iis-site-windows.yaml
deployment.apps/iis-site-windows created

After a few minutes, you should see that the deployment was created and any running pods:

  > kubectl get deployment,pods
NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/iis-site-windows   2/2     2            2           3m4s

NAME                                    READY   STATUS    RESTARTS   AGE
pod/iis-site-windows-5b6dfdf64b-k5b6r   1/1     Running   0          3m4s
pod/iis-site-windows-5b6dfdf64b-msr9s   1/1     Running   0          3m4s

4. Create a Kubernetes service 

To make pods accessible to the outside world, you need to create a Kubernetes service of type “LoadBalancer”:

  > kubectl expose deployment iis-site-windows --type="LoadBalancer"

service/iis-site-windows exposed

In a few minutes, you should see a new service with an external IP:

  > kubectl get service
NAME               TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)
iis-site-windows   LoadBalancer  80:30035/TCP

And if you go to that external IP, you will see your app:

external IP.png

This is very similar to the previous deployment to Compute Engine, with the big difference that Kubernetes is now managing the pods. If something goes wrong with the pod or one of its nodes, Kubernetes recreates and reschedules the pod for you—great for resiliency. 

Similarly, scaling pods is a single command in Kubernetes:

  > kubectl scale deployment iis-site-windows --replicas=4

deployment.extensions/iis-site-windows scaled
  > kubectl get pods
NAME                                READY   STATUS   iis-site-windows-5b6dfdf64b-2kn65   1/1     Running
iis-site-windows-5b6dfdf64b-8rvbm   1/1     Running
iis-site-windows-5b6dfdf64b-bq8dg   1/1     Running
iis-site-windows-5b6dfdf64b-zjr6c   1/1     Running

If you want to try out these steps on your own, there’s also a codelab on this topic:

Windows containers on GKE.png

And there you have it—how to run Windows containers on GKE. If you want to try out Windows Containers on GKE, sign up to get early access.