1. Overview
Container virtualization is a fast evolving technology, which aims to simplify the deployment and management of distributed applications. When people discuss containers, they usually mean Linux-based containers. This makes sense, because native Linux kernel features like cgroups introduced the idea of resource isolation, eventually leading to containers as we know them today. Until recently, only Linux processes could be containerized, but Microsoft introduced support for Windows-based containers in Windows Server 2016 and Windows 10.
It is now possible to take an existing Windows application, containerize it using Docker, and run it as an isolated container on Windows. There are two flavors of Windows containers: Windows Server and Hyper-V. You can build Windows containers on either the microsoft/windowsservercore and microsoft/nanoserver base images. You can read more about Windows containers in the Microsoft Windows containers documentation.
Google Cloud provides container-optimized VM images on which to run containers on Compute Engine. There is also a Windows VM image for containers. It comes with Docker, microsoft/windowsservercore base images installed.
In this first part of the codelab, you will deploy a Windows container app to Compute Engine. In the second part, you will deploy the same app to Kubernetes Engine.
What you'll learn
- Create a Windows Server VM for containers on Compute Engine
- Create a HelloWorld Windows container app
- Containerize the app using Docker
- Run the Windows container app on Compute Engine
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. Create a Windows VM for containers
To run Windows containers on Google Cloud, you first need a Windows VM.
In Google Cloud Platform Console, go to the Compute Engine section and create an instance. Make sure you choose Window Server 2019 Datacenter for Containers version is selected for the boot disk:
Window Server 2019 Datacenter for Containers is the latest version of Windows Server optimized for running containers.
Make sure that HTTP and HTTPS traffic is enabled to the VM.
And also make sure "Allow full access to all Cloud APIs" option is selected:
These will be useful later when we want to push/pull Docker images.
After you press "Create", it takes a couple of minutes or so for the VM to start up. After the VM has started, you should see your VM running like the following image:
4. Create a Windows password
Before you can remote desktop (RDP) into the VM, you need to create a Windows password. There are two ways of doing this. You can either set a new Windows password from the RDP button:
Another way is to click View gcloud command to reset password and run the command displayed in the dialogue in Cloud Shell:
After a few seconds, you should see the Windows password in console or Cloud Shell. Make sure you make a secure note of it for the next step.
5. RDP into the Windows VM
Now, log into the Windows VM. 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 that Docker and servercore
image is installed by default:
C:\>docker images REPOSITORY TAG IMAGE ID mcr.microsoft.com/windows/servercore ltsc2019 3e9dc86c64a9
6. Create 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 can 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 C:\my-windows-app\content C:\my-windows-app\Dockerfile C:\my-windows-app\content\index.html
Replace index.html with the following content:
<html> <head> <title>Windows containers</title> </head> <body> <p>Windows containers are cool!</p> </body> </html>
This is the page IIS will serve.
7. Build Docker image
Next, let's create a Dockerfile
for the Docker image. Notice that we're using the IIS Container image version compatible with Windows Server 2019:
FROM mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019 RUN powershell -NoProfile -Command Remove-Item -Recurse C:\inetpub\wwwroot\* WORKDIR /inetpub/wwwroot COPY content/ .
Build the Docker image and tag it with Google Container Registry (GCR) and your project id. This will be useful when we push the image to GCR 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 can see it along with its IIS dependency:
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
8. Run Windows container
Before running the container, you might need to open the port 80 from the VM Instance. Inside the Command Prompt, run the following:
C:\>netsh advfirewall firewall add rule name="TCP Port 80" dir=in action=allow protocol=TCP localport=80 C:\>netsh advfirewall firewall add rule name="TCP Port 80" dir=out action=allow protocol=TCP localport=80
We're now ready to run the Windows container. 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:
C:\>docker ps CONTAINER ID IMAGE 3d7c71a258ce gcr.io/dotnet-atamel/iis-site-windows
To see the web page, go to the External IP column of Compute Engine instance and simply open it with HTTP in the browser:
We're now running an IIS site inside a Windows container!
Note that this setup is not ideal for production. It does not survive server restarts or crashes. In a production system, you want to get a static IP for your VM and have 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. This is the second part of the codelab.
9. Cleanup
If you're attempting Running Windows containers on Google Cloud (Part 2), you can keep the VM. Otherwise, it is a good idea to either stop or delete the VM you created to avoid incurring charges. To delete the VM, go to Compute Engine VM instances page and select Delete
from the menu for the VM you want to delete:
10. Congratulations!
What we've covered
- Create a Windows Server VM for containers on Compute Engine
- Create a HelloWorld Windows container app
- Containerize the app using Docker
- Run the Windows container app on Compute Engine
Next Steps
- Running Windows containers on Google Cloud (Part 2)
- Learn more about Windows containers on Google Cloud
- Learn more about Windows on Google Cloud Platform
- Learn more about .NET on Google Cloud Platform