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:
- Ensure that the Container Registry API is enabled in your project.
- 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.
- 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 gcr.io/dotnet-atamel/iis-site-windows
The push refers to repository [gcr.io/dotnet-atamel/iis-site-windows]
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:
Create a GKE cluster with version 1.14 or higher, with IP alias enabled and one Linux node.
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:
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:
- 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
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"
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 10.107.11.34 188.8.131.52 80:30035/TCP
And if you go to that external IP, you will see your app:
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
> 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