DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Spinnaker Meets Minikube: Part 1
  • Different CPU Times: Unix/Linux ‘top’
  • Docker With Spring Boot and MySQL: Docker Swarm Part 3
  • Hardware-Accelerated OpenGL Rendering in a Linux Container

Trending

  • A Modern Stack for Building Scalable Systems
  • Unmasking Entity-Based Data Masking: Best Practices 2025
  • Agile and Quality Engineering: A Holistic Perspective
  • Docker Base Images Demystified: A Practical Guide
  1. DZone
  2. Software Design and Architecture
  3. Cloud Architecture
  4. Getting Started With Windows Containers

Getting Started With Windows Containers

By 
Jagadish Manchala user avatar
Jagadish Manchala
·
Sep. 24, 20 · Presentation
Likes (1)
Comment
Save
Tweet
Share
7.8K Views

Join the DZone community and get the full member experience.

Join For Free

Containers are a type of Operating System Virtualization that runs applications along with all its dependencies in a resource isolated process. Containers have come a long way in *nix based Operating Systems. There are many container runtimes available for running containers in Linux. Running Containers on Windows is a requirement that's been added recently 

Docker came up with an installation package for Windows that helps in running Windows containers, but the way containers run in Windows is quite different from containers running on linux. In 2016, Microsoft partnered with Docker to come up with the Docker specification that supports running Docker Windows containers. Not all Windows Operating Systems support running Containers other than Windows 10, Windows 2016 and Windows 2019. 

Docker supports running containers natively on these 3 operating systems only. Most of the Cloud providers provide AMI with prebuilt windows Container support. We can use Windows Server 2019 Datacenter with Containers VM image on Azure, and Amazon's Microsoft Windows Server 2019 Base with Containers AMI on AWS to run our windows containers.

How Does Communication Happen?

The Docker Engine communication in linux is pretty well known. All the tools like Cli, Compose etc talk to the engine using the Rest Based API calls. This engine in turn talks with Containerd or RunC to create a OCI complaint Container. The Underlying Host kernel will be shared with multiple containers and using the Kernel features like Cgroup, Chroot, Namespaces etc will provide required resources to the Containers.

The architecture looks the same for most of the top level components on the Windows-side too, but it is quite different at the host level. The kernel mode is windows is quite different from Linux kernel as this includes not just the kernel but also including other services. Various managers for  Objects, processes, Memory, Security, Cache, Plug in Play (PnP), Power,  Configuration, and I/O collectively called Windows Executive (ntoskrnl.exe) are available. 

So there are no separate Namespace or Cgroup implementations in Windows  instead  came up with “Compute Service Layer” at Os level which provides namespaces, resource control and UnionFS capabilities. This layer is responsible for managing the containers like start,stop etc which containerd in linux does. So there will be no separate containers or runC in Windows. All the tasks of these will be done by this Compute layer.

What Is Different From Linux Containers?

The way that the Windows Containers run on the Windows platform is quite different from the way Linux containers run on *nix based Operating systems. 

Windows is a highly integrated operating system that exposes its API with DLL’s and not by SysCalls. In Windows, an application cannot directly make a system call like in *nix based systems. Every kernel action that the application wants to perform will communicate with the .dll ( dynamic linked library ) that talks to the windows manager which in turn performs the kernel action. 

The Underlying process of how the DLL’s work and how they talk to the Operating System services is undocumented. In basic terms, all kernel actions, like allocating memory, hardware requirements, etc will go through .dll to the Windows manager, which in turn provide the requested service. This goes in the same way for applications running inside the windows containers. 

For every kernel action requested by the application running inside the container would go through the .dll and then to the windows Operating system. The application running in the container would require the same .dll files for routing the kernel actions to the Windows operating system. For this, the windows container will have the application running and also certain services that are required for the application to connect to the Windows operating system  and other things. This is what we call Windows server containers or Process Containers.

Isolation modes

In order to run a container, Windows provides two different modes of runtime isolation i.e Process Isolation and Hyper-V Isolation. These 2 modes let windows containers run in different ways. 

Process Containers 

As we can see in the above image, the windows server containers or process containers will have both application process (ASP.NET or C#) and system process (.dll and other api related calls ). This is the reason why the Windows container images are huge in-size since we have the application code along with the system process like dll etc. 

This is where a very important thing comes into picture. That is in a Linux Operating system, we can run a Centos Container on a RHEL machine or a SUSE linux container on a Ubuntu machine. This happens because the container shares the same host kernel. But in Windows, we have a dependency with the system process (.dll etc) running inside a container which might change from build to build in Windows. For this reason, we can only run a Windows container on a Windows machine, which has the same operating system flavors. That is, we cannot run a Windows container built with Windows 10 on a Windows 2016 server or Windows 2019 server. We need to have the same flavor of operating system for containers and also running on host. Most of the time, the container will start but some of its features will be restricted or not guaranteed.

Creating Your First Windows Process Container

For creating our windows container, we will be using Amazon AMI for creating our windows instance which have Docker already installed. Create a Windows Ec2 Instance from the AMI “Windows_server-2019-ECS_Optimized” ( ami-05f51a63adfbce152). I will be using the Windows 2019 Base machine with Docker preinstalled.

We ran the below command to pull the 2019 image and run the container as below,

docker run mcr.microsoft.com/windows/servercore:ltsc2019

Or we can also run the Windows process container by passing the isolation parameter as below

docker run -it --isolation=process mcr.microsoft.com/windows/servercore:
ltsc2019 cmd

The default entrypoint for each Windows base OS image as a console, either cmd.exe or PowerShell. The command can be something similar to how we run in Linux as below,

docker run -it mcr.microsoft.com/windows/servercore:ltsc2019 cmd.exe 

docker run -it mcr.microsoft.com/windows/servercore:ltsc2019 powershell.exe

In both the cases, we are running the same docker windows image with either cmd.exe or powershell.exe are landing zones similar to bash. The default is cmd.exe. Most of the commands for Docker remain the same on both Linux and windows machines. There are 4 types of images provided by Microsoft. 

Windows Server Core : For supporting traditional .net applications

Windows Nano Server : for core .net applications

Windows : Provides full windows capabilities

Windows IOT : for IOT applications.

Many Windows users want to containerize applications that have a dependency on .NET. In addition to the four base images described here, Microsoft publishes several Windows container images that come pre-configured with popular Microsoft frameworks, such as the .NET framework image and the ASP .NET image.

We can see that we have 2 base images available for Windows .net applications, windows server Core and nano server. Both these images are quite commonly used but have few differences. Nano Server has a significantly smaller API in which some of the windows services like powershell, WMI etc are not available. Nano Server was built to provide just enough API surface to run apps that have a dependency on .NET core.

Note - The important point over here, Microsoft does not publish images with the latest tag, it will always be a ltse or other thing ( Long term servicing channel ).Please declare a specific tag when pulling or referencing images from this repo.

Building Your First Docker Windows Image for Windows Containers

Building the Docker Image is quite the same as the Linux Image. Below is the Dockerfile contents for a Nginx process to run,

Dockerfile
x
 
1
FROM mcr.microsoft.com/windows/servercore:ltsc2019
2
LABEL Description="Nginx" Vendor="Nginx" Version="1.0.13"
3
RUN powershell -Command \
4
    $ErrorActionPreference = 'Stop'; \
5
    Invoke-WebRequest -Method Get -Uri http://nginx.org/download/nginx-1.9.13.zip -OutFile c:\nginx-1.9.13.zip ; \
6
    Expand-Archive -Path c:\nginx-1.9.13.zip -DestinationPath c:\ ; \
7
    Remove-Item c:\nginx-1.9.13.zip -Force
8
WORKDIR /nginx-1.9.13
9
CMD ["/nginx-1.9.13/nginx.exe"]


All the Commands above are quite the same as those we use in Linux Image Building.

Build the image using the docker build command as,

PowerShell
xxxxxxxxxx
1
22
 
1
PS C:\Users\Administrator\windows-docker-files> docker build -t first-windows-dockerfile .
2
Sending build context to Docker daemon  2.048kB
3
Step 1/5 : FROM mcr.microsoft.com/windows/servercore:ltsc2019
4
 ---> 8351e66084ac
5
Step 2/5 : LABEL Description="Nginx" Vendor="Nginx" Version="1.0.13"
6
 ---> Running in 99a432826c7b
7
Removing intermediate container 99a432826c7b
8
 ---> 20ab94cb14d8
9
Step 3/5 : RUN powershell -Command     $ErrorActionPreference = 'Stop';     Invoke-WebRequest -Method Get -Uri http://nginx.org/download/nginx-1.9.13.zip -OutFile c:\nginx-1.9.13.zip ;     Expand-Archive -Path c:\nginx-1.9.13.zip -DestinationPath c:\ ;     Remove-Item c:\nginx-1.9.13.zip -Force
10
 ---> Running in c80bfc7227e1
11
Removing intermediate container c80bfc7227e1
12
 ---> 7ccd7d81b336
13
Step 4/5 : WORKDIR /nginx-1.9.13
14
 ---> Running in a46cf2a47431
15
Removing intermediate container a46cf2a47431
16
 ---> 7f8fd47864de
17
Step 5/5 : CMD ["/nginx-1.9.13/nginx.exe"]
18
 ---> Running in 75821cd15632
19
Removing intermediate container 75821cd15632
20
 ---> f793d005d447
21
Successfully built f793d005d447
22
Successfully tagged first-windows-dockerfile:latest

Once the image is build, check the images using the “docker images”

PowerShell
xxxxxxxxxx
1
 
1
PS C:\Users\Administrator\windows-docker-files> docker images                     
2
REPOSITORY                  TAG       IMAGE ID           CREATED           SIZE 
3

          
4
first-windows-dockerfile    latest    f793d005d447      2 minutes ago      4.85GB


Run the Docker image using the “docker run” command as,

C:\Users\Administrator\windows-docker-files> docker run -d -p 80:80 
first-windows-dockerfile

ef113bcb3567711958909394c6beff4082e618bea92dd57374a7cfb11d847519                                                                     

Check if the docker container is running or not using,

PowerShell
xxxxxxxxxx
1
 
1
PS C:\Users\Administrator\windows-docker-files> docker ps 
2

          
3
CONTAINER ID    IMAGE                            COMMAND                                                                                                             ef113bcb3567    first-windows-dockerfile          "/nginx-1.9.13/nginx…"   
4

          
5
*******


Hyper-V Containers

With the above Windows Process Containers, we have a challenge where there is a dependency on the Host Operating system version. As we said earlier, we have to have both the Container Operating system version and the Host version as same Since we will be communicating with system processes ( dll). If there is any change on the Host Operating system, this can break the application running in the container.

This is where Hyper-V containers came in use. Hyper-V is a hypervisor-based virtualization technology for certain x64 versions of Windows. The hypervisor is core to virtualization. It is the processor-specific virtualization platform that allows multiple isolated operating systems to share a single hardware platform.

Rather than running a Windows Container on a Host Operating system, we run the containers on a Hyper-V virtual machine which in-turn run on the Host machine. First Hyper-V containers use the base image defined for the application and automatically create a Hyper-V VM using that base image. Inside the VM we will have the necessary binaries and libraries for our application run along with the windows Container. The windows container will have the application along with windows services to talk to the host kernel. The only difference is the Windows container is now running inside a Hyper-V VM which provides kernel isolation and separation of the host patch/version level from that used by the application. The other advantage is that we can use multiple hyper-V containers and can use the common base image and no management is required in creating the Hyper-V VM as it is taken care automatically.

Windows container architecture

Creating your first Hyper-V Container

For running a Windows Process Container, we ran it without passing the isolation parameter but for the Hyper-V container, we have to pass the isolation parameter. Docker by default creates a Windows Process Container if we dont pass the isolation parameter but we have to pass the isolation parameter for Hyper-V containers.

Run the Hyper-V container using,

docker run -it --isolation=hyperv mcr.microsoft.com/windows/servercore:
ltsc2019 cmd

Once you run the above command, we can still see the docker containers using the “docker ps” command as below,

PowerShell
 
xxxxxxxxxx
1
 
1
PS C:\windows\system32> docker ps
2

          
3
CONTAINER ID  IMAGE    COMMAND       CREATED    STATUS   PORTS  NAMES
4

          
5
1fa84490a13b  mcr.microsoft.com/windows/servercore:ltsc2019   "cmd"               ******


Windows also provides another way to check if the Hyper-V container is up and running. We can the processes using powershell “get-process” command as below,

PowerShell
xxxxxxxxxx
1
 
1
PS C:\windows\system32> get-process -Name vmwp
2

          
3
Handles  NPM(K)    PM(K)       WS(K)     CPU(s)     Id      SI   ProcessName
4

          
5
-------    ------       -----          -----         ------     --       --    -----------
6

          
7
   1565     18         8764         17028       2.45     9792   0     vmwp
8

          
9
    280      14         5104         19148       1.47     10148 0      vmwp


For every Hyper-V container, there will be a vmwp process created. There is a Virtual machine worker process ( vmwp ) for every virtual Machine that gets created. This is actually the running virtual machine that is encapsulating the running container and protecting the running processes from the host operating system.

Image2Docker 

Since now we have support for running containers on Windows but in the earlier phases we have many of the windows applications running in a light-weight Hyper-V container or Virtual machines. So there is a need for a tool to convert or analyze these Virtual machines to identify what type of application is running and convert them to Dockerfile that can be used to build the windows image.

Image2Docker is a powershell module that will analyze the Virtual Hard disk image(vhdk), scan for the most common windows components and suggest a Dockerfile.

Install the Powershell Module

Start the powershell command prompt and run the following commands to install the Image2Docker module as below,

PowerShell
xxxxxxxxxx
1
 
1
PS C:\dockfile> Install-Module Image2Docker
2
PS C:\dockfile> Import-Module Image2Docker


Once the module is installed, run the “Get-WindowsArtifact” command to see the supported Windows components as below

PowerShell
 
xxxxxxxxxx
1
 
1
PS C:\dockfile> Get-WindowsArtifact
2
AddRemovePrograms
3
AllWindowsFeatures
4
Apache
5
DHCPServer
6
DNSServer
7
IIS
8
MSMQ
9
SQLServer


For the article, I have created a Virtual Machine and used this for our Image2Docker scanning as below,

PowerShell
xxxxxxxxxx
1
 
1
PS C:\dockfile> ConvertTo-Dockerfile -ImagePath "C:\Users\Public\Documents\Hyper-V\Virtual Hard Disks\Test1.vhdx" -Artifact IIS -ArtifactParam aspnet-webapi -OutputPath c:\i2d2


The Command we will be using is “ConverTo-Dockerfile” and we will be passing the vhdx location for -ImagePath, Artifact type and OutputPath for generating the Dockerfile location.

PowerShell
xxxxxxxxxx
1
 
1
ConvertTo-Dockerfile 
2
-ImagePath " C:\Users\Public\Documents\Hyper-V\Virtual Hard Disks\Test1.vhdx"
3
-Artifact IIS
4
-ArtifactParam aspnet-webapi 
5
-OutputPath c:\i2d2


In order to run this command we have to first stop the Virtual Machine. This will mount the vhdx image file and once the scan is done, it will unmount the image. This will also generate the Dockerfile for us in the OutputPath location as we pass.

In the OutputPath location, run the “docker build” command as below,

PowerShell
 
xxxxxxxxxx
1
 
1
PS C:\dockfile> docker build --isolation hyperv -t sample .
2
PS C:\dockfile> docker run -d --isolation hyperv sample


Two important things to remember here is to build and run the image passing the isolation parameter. The Image build will also fail if we don't pass the isolation parameter as above.

More to Come, Happy learning :-) . 

Docker (software) operating system Hyper-V application Virtual Machine Linux kernel Host (Unix) PowerShell Command (computing) Machine

Opinions expressed by DZone contributors are their own.

Related

  • Spinnaker Meets Minikube: Part 1
  • Different CPU Times: Unix/Linux ‘top’
  • Docker With Spring Boot and MySQL: Docker Swarm Part 3
  • Hardware-Accelerated OpenGL Rendering in a Linux Container

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!