1. Overview
In the first part of the lab, you deployed a Windows container app to Google Compute Engine (GCE). This second part of the lab builds on the first part and you deploy the same app to Google Kubernetes Engine (GKE) for added resiliency and scalability.
What you'll learn
- Push a Windows container to Google Container Registry
- Create a Kubernetes cluster with Windows nodes on GKE
- Run Windows container as a pod in GKE
- Expose the Windows container behind a Kubernetes service
What you'll need
How will you use this tutorial?
How would rate your experience with Google Cloud Platform?
2. Setup and Requirements
For this codelab, you need a Google Cloud Platform project to interact with PowerShell. If you have an existing project, you can either use that or you can create a new project using the following steps.
Self-paced environment setup
If you don't already have a Google Account (Gmail or GSuite), you must create one. Sign-in to Google Cloud Platform Console ( console.cloud.google.com) and create a new project:
Remember the project ID, a unique name across all Google Cloud Platform projects. It will be referred to later in this codelab as PROJECT_ID
.
Next, you'll need to enable billing in Google Cloud Platform Console in order to use Google Cloud Platform resources like Google Cloud Datastore and Cloud Storage.
New users of Google Cloud Platform are eligible for a $300 free trial. Running through this codelab shouldn't cost you more than a few dollars, but it could be more if you decide to use more resources or if you leave them running (see the "cleanup" section at the end of this document).
3. RDP into the Windows VM
Log into the Windows VM that you already created in the first part of the lab. You can simply click on the RDP button of the VM (or use your own RDP client if you like):
Once inside the VM, open a command prompt in admin mode. In the command prompt, you can see the Windows container image: iis-site-windows
C:\>docker images REPOSITORY TAG gcr.io/dotnet-atamel/iis-site-windows latest mcr.microsoft.com/windows/servercore/iis windowsservercore-ltsc2019 mcr.microsoft.com/windows/servercore ltsc2019
In the next step, we will push this image to Google Container Registry (GCR).
4. Push container image to GCR
We need to host the Windows container image in a public image repository before we can use it in other part of Google Cloud. Google Container Registry (GCR) is a good place for container images.
To push a container image from a Windows VM to GCR, we need to:
- Make sure that the Container Registry API is enabled in your project.
- Configure Docker to point to GCR.
Make sure the Container Registry API is enabled:
C:>gcloud services enable containerregistry.googleapis.com
Configure Docker to point to GCR:
C:>gcloud auth configure-docker .. Do you want to continue (Y/n)? Y Docker configuration file updated.
Now, you can push the image to GCR (replace dotnet-atamel
with your project id):
C:>docker push gcr.io/dotnet-atamel/iis-site-windows The push refers to repository [gcr.io/dotnet-atamel/iis-site-windows] 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
If you go to GCR section in Cloud Console, you can see the image:
5. Create a Kubernetes cluster with Windows nodes
Before creating a Kubernetes cluster, make sure the project id set to your project and a compute/zone is set the zone you want (replace your-project-id
and ${ZONE}
with your preferred zone):
gcloud config set project your-project-id export ZONE=europe-west1-b gcloud config set compute/zone ${ZONE}
Creating a Kubernetes cluster in GKE with Windows nodes happens in 2 steps:
- Create a GKE cluster with IP alias and 1 Linux node. At least 1 Linux node is needed before Windows nodes can be added to the cluster.
- Add a Windows node pool to the GKE cluster.
Create a GKE cluster. Replace CLUSTER_NAME
with your preferred name for the cluster. Also replace CLUSTER_VERSION
with version 1.16.8-gke.9
or higher:
export CLUSTER_NAME=your-cluster-name export CLUSTER_VERSION=your-cluster-version gcloud container clusters create ${CLUSTER_NAME} \ --enable-ip-alias \ --num-nodes=2 \ --cluster-version=${CLUSTER_VERSION}
Once we have the basic GKE cluster, we can go ahead and add a Windows pool for Windows nodes to it:
gcloud container node-pools create windows-node-pool \ --cluster=${CLUSTER_NAME} \ --image-type=WINDOWS_LTSC \ --no-enable-autoupgrade \ --machine-type=n1-standard-2
Notice that we're 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 users disable node autoupgrade for Windows node pools.
For Windows Server containers in GKE, you're already licensed for underlying Windows host VMs – containers need no additional licensing.
In the end, the GKE cluster is ready with 2 Linux nodes and 3 Windows nodes:
6. Verify cluster initialization
Before running our Windows container as a pod on GKE, make sure the cluster is initialized.
Authenticate kubectl
with the GKE cluster by copying/pasting the gcloud
command in the Connect button:
Alternatively, you can just run the following command:
gcloud container clusters get-credentials ${CLUSTER_NAME}
kubectl
is now setup to manage our cluster.
Before using the cluster, wait for several seconds until windows.config.common-webhooks.networking.gke.io
is created. This webhook adds scheduling tolerations to Pods created with the kubernetes.io/os: windows
(or beta.kubernetes.io/os: windows
) node selector to ensure they are allowed to run on Windows Server nodes. It also validates the Pod to ensure that it only uses features supported on Windows.
kubectl get mutatingwebhookconfigurations NAME CREATED AT windows.config.common-webhooks.networking.gke.io 2020-01-20T15:09:16Z ...
Now the cluster is ready for Windows containers.
7. Run Windows container as a pod in GKE
Let's create an iis-site-windows.yaml
file to describe our Kubernetes deployment (replace ${PROJECT_ID}
with your project id):
apiVersion: apps/v1 kind: Deployment metadata: name: iis-site-windows labels: app: iis-site-windows spec: replicas: 2 selector: matchLabels: app: iis-site-windows template: metadata: labels: app: iis-site-windows spec: nodeSelector: kubernetes.io/os: windows containers: - name: iis-site-windows image: gcr.io/${PROJECT_ID}/iis-site-windows ports: - containerPort: 80
Note that we're creating 2 pods with the image we pushed earlier to GCR. We'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 the deployment created and pods running:
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
8. Create a Kubernetes Service
To make pods accessible to the outside world, we need to create a Kubernetes service with LoadBalancer type:
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 10.107.11.34 104.155.45.254 80:30035/TCP
And if we go to that external IP, we will see our app:
This is very similar to the previous lab where we deployed to GCE but the big difference is that Kubernetes is managing the pods. If something goes wrong with the pod or the node that the pod is running, Kubernetes will recreate and reschedule the pod for us. 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
9. Cleanup
Once you're done testing, it's a good idea to delete the cluster.
First, delete the service and the deployment, which also deletes your external load balancer:
kubectl delete service,deployment iis-site-windows service "iis-site-windows" deleted deployment.extensions "iis-site-windows" deleted
Next, delete your cluster:
gcloud container clusters delete windows-cluster
10. Congratulations!
What we've covered
- Push a Windows container to Google Container Registry
- Create a Kubernetes cluster with Windows nodes on GKE
- Run Windows container as a pod in GKE
- Expose the Windows container behind a Kubernetes service
Next Steps
- Sign up for Early Access for Windows container on GKE
- Learn more about Windows containers on Google Cloud
- Learn more about Windows on Google Cloud Platform
- Learn more about .NET on Google Cloud Platform