This content is part of the Essential Guide: A guide to Microsoft Windows Server 2016

Essential Guide

Browse Sections

How to deploy Windows containers in Microsoft Azure

Want to build and manage your own Windows Server containers? Here's how to do it using native Docker commands and a PowerShell module.

Docker is an application virtualization technology that's quite popular in the free and open source software community....

A Docker container takes a given app -- Web server, database server, among others -- and runs it and all its dependencies in an isolated environment.

DevOps engineers and programmers like Docker because they can spin up entire multicontainer environments within a few seconds. The containers are network-aware and behave as if they're running on their own dedicated hardware. When a container is no longer needed, it can be stopped and deleted with very little latency.

Microsoft's Jeffrey Snover, technical fellow and lead architect for the Enterprise Cloud Group, and Mark Russinovich, CTO of Azure, both feel strongly about supporting free and open source software in general and Docker containers in particular.

In Windows Server 2016 Technical Preview 4 (TP4), the Docker runtime is integrated with the Windows Server operating system (OS). The Windows and Linux kernels are fundamentally different, so we can't run Linux-based containers on a Windows container host. Instead, Microsoft offers Windows Server-based containers. This tip will show how to deploy Windows containers from an Azure-based virtual machine (VM) host running Windows Server 2016 TP4.

Creating the container host VM

The physical server or VM that hosts the Docker runtime environment and associated containers is called, not surprisingly, a container host. Although we could set up an on-premises container host by downloading the TP4 ISO and following some rather tedious setup instructions, I thought it easier to do the same thing in the Azure public cloud.

If you don't already have a Microsoft Azure account, sign up for a free trial. You'll get $200 in service credit that covers a month of Azure access.

Log in to the Azure portal and create a VM using the Windows Server 2016 Core with Containers Tech Preview 4 image, as shown in Figure 1.

Microsoft Azure container
Figure 1: Microsoft has a container-enabled Windows Server 2016 image available in the Azure cloud. ALT

 After Azure creates the container host VM, click Connect -- shown in Figure 2 -- to download a preconfigured Remote Desktop Protocol (RDP) .rdp file.

Container host VM
Figure 2: We use Remote Desktop Protocol to connect to the container host VM in Azure.

 There are a few important features to be aware of in this Azure-based VM:

Getting comfortable with the commands

Next, open the RDP connection to connect to the container-host VM. You'll find yourself at a cmd.exe prompt, so type powershell to enter an administrative PowerShell console session. First, let's verify the containers feature is installed:

Get-WindowsFeature -Name Containers

Display Name         Name             Install State

------------         ----             -------------

[X] Containers      Containers        Installed

Next, we'll make sure the Docker service is present and started:

Get-Service -Name Docker

Status   Name               DisplayName

------   ----               -----------

Running  Docker             Docker Daemon

Excellent on both counts. We can manage Windows Server containers in one of two ways:

Those who've used Docker in open source environments are likely to start with the native Docker commands, which behave the same way they do under Linux. However, I suggest we use the PowerShell commands because we already understand PowerShell syntax. Also, in my experimentation, I've found the PowerShell commands to be more reliable than the native Docker commands.

Let's take a quick look at the Containers commands to see what's available:

Get-Command -Module Containers | Select-Object -Property Name | Sort-Object -Property Name



































Creating a Windows Server container

In Docker nomenclature, a container is an instance of a container image. In turn, we can look at a container image as a blueprint for a virtualized OS and application.

We can use Get-ContainerImage to view the VM's one prebuilt container image:


Name                Publisher      Version          IsOSImage

----              ---------         -------         ---------

WindowsServerCore   CN=Microsoft    10.0.10586.0    True

As you can see, we have a single Windows Server OS image named WindowsServerCore. We'll use New-Container to create a new container named core1 using this image as a template:

New-Container -Name 'core1' -ContainerImageName 'WindowsServerCore' -SwitchName 'Virtual Switch' -RuntimeType Default

Name     State     Uptime       ParentImageName

----     -----     ------       ---------------

core1    Off       00:00:00     WindowsServerCore

I want to discuss two parameters from the previous code in greater detail. First, the -SwitchName parameter binds the container to a Hyper-V virtual switch running on the container host.

The virtual switch is important because it allows networking between the container, the host and -- potentially -- the world beyond. Try this:

$switch = Get-VMSwitch -Name 'Virtual Switch'


So we see that, under the covers, the virtual switch uses Network Address Translation with the address range. Thus, we can expect that our container will have a IPv4 address.

Second, the -RuntimeType parameter of the New-Container cmdlet specifies the isolation level of the container. We have two choices here:

  • Default: This is the "garden variety" Windows Server container isolation, which assumes a high degree of trust between containers and the host.
  • Hyper-V: This is a much more strongly isolated container environment that's intended for containers that require total isolation for security purposes.

Note that Microsoft doesn't support Hyper-V containers in Azure. However, you can deploy this container type when running Windows Server 2016 TP4 on premises. I've had mixed results, but that's to be expected because Windows Server 2016 and the Docker integration are in an unfinished -- and therefore highly volatile -- state at this point.

Working within Windows containers

Windows Server 2016 doesn't start new containers by default. We do it manually by invoking Start-Container:

Start-Container -Name 'core1'

As you'd expect, we use Get-Container to see our containers in much the same way we used Get-ContainerImage to view our container images:


Name    State      Uptime              ParentImageName

----    -----      ------              ---------------

core1   Running    00:00:10.4520000    WindowsServerCore

We can interact with the container through PowerShell remoting commands. For starters, let's log in to the container with Enter-PSSession:

Enter-PSSession -ContainerName 'core1' -RunAsAdministrator

[core1]: PS C:\Windows\system32>

Now, any commands we issue will take place on core1 instead of the container host. For example, let's check the container's IPv4 address:

[core1]: PS C:\Windows\system32> Get-NetIPAddress | Select-Object -Property IPv4Address



Just as we suspected: The container's IP address is NAT'ed to the host by means of that virtual switch. Type exit to detach from the container and return to the host.

We send commands to the container by using Invoke-Command:

Invoke-Command -ContainerName 'core1' -ScriptBlock { Get-Service -Name Server }

Status     Name          DisplayName      PSComputerName

------     ----          -----------      --------------

Stopped   LanmanServer   Server           core1

If you've used Invoke-Command, then you are probably accustomed to the -ComputerName parameter to specify your target computers. In Windows Server 2016, the new -ContainerName parameter enables us to target containers.

Cleaning the environment

Let's finish this test by stopping our container:

Stop-Container -Name 'core1'

Then we'll delete the container:

Remove-Container -Name 'core1' -Force

Close the RDP session and return to the Azure portal. Be sure to stop the VM -- shown in Figure 3 -- to avoid any billing surprises, or, more likely, prematurely running through your Azure credit.

Terminating the container host VM
Figure 3: If you're not using an Azure service, be sure to turn it off to avoid unexpected charges.

Next Steps

Administrators can take steps to make Hyper-V containers more secure

What containers mean for traditional Windows applications

Nested virtualization in Hyper-V makes containers possible

Dig Deeper on Microsoft Azure cloud services