Containers & Kubernetes
How to deploy a Windows container on Google Compute Engine
Last year, we published a blog post and demonstrated how to deploy a Windows container running Windows Server 2016 on Google Compute Engine. Since then, there have been a number of important developments. First, Microsoft announced the availability of Windows Server 2019. Second, Kubernetes 1.14 was released with support for Windows nodes and Windows containers.
Supporting Windows workloads and helping you modernize your apps using containers and Kubernetes is one of our top priorities at Google Cloud. Soon after the Microsoft and Kubernetes announcements, we added support for Windows Server 2019 in Compute Engine and Windows containers in Google Kubernetes Engine (GKE).
Given this expanded landscape for Windows containers on Google Cloud, let’s take a fresh look at how best to deploy and manage them. In this first post, we’ll show you how to deploy an app to a Windows container on Windows Server 2019 on Compute Engine. Then stay tuned for the next post, where we’ll deploy and manage the same Windows container via Kubernetes 1.14 on GKE.
Let’s get started!
Create a Windows Server instance on Compute Engine
First, you need a Windows Server instance on which to run a Windows container. Compute Engine comes with many flavors of Windows Server (Server vs. Server Core), and many versions (2008 to 2019). There are also container-optimized versions that come with Docker and some base images already installed.
For this exercise, let’s choose the latest container-optimized version of Windows Server. In Google Cloud console, create a VM with the Windows Server 2019 Datacenter for Containers image:
Make sure that HTTP/HTTPS traffic is enabled:
And also make sure to select “Allow full access to all Cloud APIs”:
Allowing HTTP/HTTPs and Cloud API traffic will be useful later when we want to push/pull Docker images.
Once the VM is up and running, you can set a Windows password and connect into it using Remote Desktop (RDP). Inside the VM, open a Command Prompt in Admin mode and type the following:
REPOSITORY TAG IMAGE ID
mcr.microsoft.com/windows/servercore ltsc2019 3e9dc86c64a9
As you can see, Docker is already installed and the Windows Server Core image for 2019 is already on the VM (“pulled,” in Docker-speak). We will use this as a base image for our Windows container app.
Create a Windows container app
For the app inside the Windows container, let’s use an IIS Web Server. IIS has an image for Windows Server 2019. We could use the image as is and it will serve the default IIS page. But let’s do something more interesting and have IIS serve a page we define.
Create a folder called my-windows-app with the following folder and file structure:
C:\my-windows-app>dir /s /b
Replace index.html with the following content:
<p>Windows containers are cool!</p>
This is the page IIS will serve.
Build a Docker image
Next, let’s create a Dockerfile for the Docker image. Notice that we’re using the IIS Container image version that is compatible with Windows Server 2019:
RUN powershell -NoProfile -Command Remove-Item -Recurse C:\inetpub\wwwroot\*
COPY content/ .
Build the Docker image and tag it with Google Container Registry and your project id. This will be useful when we push the image to Container Registry later (replace dotnet-atamel with your project id):
C:\>docker build -t gcr.io/dotnet-atamel/iis-site-windows .
Once the Docker image is built, you will be able to see it along with its IIS dependency:
REPOSITORY TAG gcr.io/dotnet-atamel/iis-site-windows latest
Run your Windows container
We’re now ready to run the Windows container. From inside the command prompt, run the container and expose it on port 80:
C:\>docker run -d -p 80:80 gcr.io/dotnet-atamel/iis-site-windows
You can check that the container is running:
CONTAINER ID IMAGE
To see the web page, go to the External IP column of the Compute Engine instance and simply open it with HTTP in the browser:
We’re now running an IIS site inside a Windows container!
If you want to try out these steps on your own, we also published a codelab on this topic:
Note that this setup is not ideal for production. It does not survive server restarts or crashes. In a production system, you’ll want a static IP for your VM and create a startup script to start the container. This will take care of server restarts but doesn’t help so much for server crashes.
To make the app resilient against server crashes, you can run the container inside a pod managed by Kubernetes. The process for doing this will be the topic of our next blog post.