Docker's Close Integration with Windows Server
Windows Server 2016 TP4 and TP5 now support Docker containers. Learn what this means for the future of IT system and application architectures and how to set up and manage a host using Windows PowerShell.
- By Michael Otey
The ability to run proprietary and open source containers in the next version of Windows Server promises to be one of the key breakthroughs that will transform Microsoft's server OS into a next-generation cloud platform. Not only does support for containers open the door for organizations to build modern, cloud-scale applications, but those that are Windows-based and open source, portable across servers, virtual machines (VMs) and clouds.
While container technology has been part of Linux for some time, its addition to Windows Server is entirely new with Windows Server 2016 TP4 and updated in TP5. Windows Server Containers can be used to rapidly deploy applications to Windows Server systems. Containers essentially virtualize at the OS level, which makes them far more lightweight than VMs that virtualize at the hardware level. In addition, containers are more easily updated than a VM, enabling businesses to have a more rapid release cycle. Windows Server 2016 supports two types of containers: Windows Server Containers and Hyper-V Containers (as Brien M. Posey wrote about back in March in "A Tale of 2 Container Deployments"). Windows Server Containers run directly on the Windows Server OS and they're more lightweight than Hyper-V Containers. Like their name implies, Hyper-V Containers run inside a Hyper-V VM, which means they have somewhat higher resource requirements, but they also offer increased security and application isolation over Windows Server Containers. Both Windows Server Containers and Hyper-V Containers can be managed using Docker or Windows PowerShell.
Microsoft's announcement in 2014 that it would support Docker containers in Microsoft Azure and Windows Server opened the path for infrastructure and application designed purely for the Microsoft platform -- including the .NET Framework, Hyper-V and the server OS kernel itself -- to offer new levels of portability across apps, systems and cloud services. Using the Windows Server 2016 TP5 that now includes support for Docker containers introduced in TP4, I can describe how to deploy and manage Windows Server Containers with Docker. First, let's take a closer look at how containers compare to VMs to get a better understanding of how Windows Server Containers work; then you'll see how you can get started using them in Windows Server 2016 TP5.
Containers vs. Virtual Machines
Containers are much like the next generation of virtualization beyond server virtualization. Instead of virtualizing at the hardware level like a VM, a container essentially virtualizes at the OS level. Containers run at a layer on top of the Windows Server OS and they share the OS kernel. This enables containers to run with lower overhead than VMs and gives them a much smaller footprint. Containers can enable organizations to improve application performance, increase the density of apps running on their servers and speed up application deployment. You can see an overview of the difference between containers and VMs in Figure 1.VMs rely on a hypervisor, which is normally installed directly on bare metal system hardware. Each VM has its own OS and applications. VMs can be moved between virtualization hosts without changing the VM characteristics and without any end user downtime by using technologies such as live migration or VMware vMotion. As you can see in Figure 1, the container environment is different. The container runtime engine, like Docker, is installed on top of the host OS and every containerized application shares the same underlying OS. Applications are installed in the container image and the container is what you distribute. Containers are more resource-efficient than VMs, which means a single system can potentially host far more containers than VMs.
From a practical management perspective, containers -- unlike VMs -- share the same kernel as the underlying OS. This means containers do not have the storage or networking flexibility that VMs do. Containers can run on either physical or virtual servers and can be updated incrementally without the need to redeploy the entire container. At this point, Windows Server Containers do not support all applications. For the most current list of supported applications, go here.
The Windows Server Docker Architecture
At its core, Docker is a platform that allows software developers and IT professionals to develop and deploy applications in container images. These images are portable and isolated from each other. Docker provides an abstraction between the application layer and the OS layer. Developers can create applications in Docker containers and copy and run those applications without changes on the physical servers, VMs or cloud Infrastructure-as-a-Service (IaaS) VMs that run the containers (see Figure 2).
Using a client-server architecture, the Docker client talks to a daemon (aka service). The client and daemon can run on the same or different systems and it's the daemon that executes the container image. To create images, Docker uses a union file system that allows several file systems to be mounted simultaneously, but to appear as one. You install applications on top of a base OS image and Docker creates a snapshot using Another Union File System (AuFS). The resulting image is lightweight and read-only. Changes made to the container are sandboxed and they're not propagated to the underlying OS. Updating images is easy because only the differential changes since the last snapshot need to be distributed each time a modification is made to an application. Container images are stored in the Docker registry. This is part of the Docker implementation and is different from the Windows system registry. You can manage Windows Server Containers with either Docker or PowerShell, but at the time of this writing, images created with Docker can't be managed using Windows PowerShell and images created with PowerShell can't be managed with Docker.
Requirements for Creating Containers with Docker
Windows Server Containers and Hyper-V Containers have similar requirements. The basic requirements for using Windows Server Containers or Hyper-V Containers are:
- Windows Server 2016 TP4 or an Azure Windows Server 2016 VM
- Administrator permissions on the host
- 20GB of available storage
- Hyper-V Containers require the Hyper-V role
- Hyper-V Containers require Windows Server 2016 with Nested Virtualization enabled
- Currently, the build and patch level of Windows Server Container images must match the host OS, but this might change by the final releaseWindows Server Containers can only run Windows applications -- even with Docker. Any Linux-based Docker containers won't run under Windows. They will only run under Linux. This is because containers share the same common OS as the container host.
Setting up the Windows Server Host
There are several steps required to prepare a Windows Server host for running containers:
- Container feature: Enables use of Windows Server and Hyper-V containers
- Optionally create a container network: Containers use a virtual switch on the host for network connectivity
- Install Container OS Images: OS images provide the base for container deployments
- Install Docker: Docker provides container management, but you can also use PowerShell
Enabling Windows Container Support and Installing Docker with PowerShell
There are a few different methods you can use to install Windows Server Containers support on your system. The most straightforward way is to launch Server Manager and the run the Add Roles and Features Wizard. On the Select features dialog, select the Containers option, as shown in Figure 3.
When you add the Containers feature you essentially install a setup of Windows Server Container PowerShell commands. You can also install the Containers feature using PowerShell with the following command:
PS C:\> Install-WindowsFeature containers
The system needs to be rebooted following the installation of the Containers feature. You can run the Get-ContainerHost command to verify the Containers feature has been installed. After the Containers feature has been installed, you can run the following PowerShell command to see the different PowerShell Container cmdlets (see Figure 4):
PS C:\> Get-Command -Module Containers
Note: In TP5 running this command and various others produces the following message: "WARNING: Based on customer feedback, we are updating the Containers PowerShell module to better align with Docker. As part of that some cmdlet and parameter names may change in future releases. To learn more about these changes, as well as to join in the design process or provide usage feedback, please refer to Microsoft's PowerShell for Docker documentation."
Unlike adding most of the other Windows Server 2016 features, adding just the Containers feature isn't the only step you need to perform to use Windows Server Containers and Docker. You also need to perform several other configuration steps. Microsoft provides a PowerShell script that can help you quickly complete the initial Windows Server Container host configuration.
Performing the configuration steps either manually or by running the script is required even if you enable the Containers feature in Windows Server 2016 TP5. This might change somewhat in the final release, but for Windows Server 2016 TP4, if you don't run the setup commands and you try to run Docker you'll get a "Docker isn't recognized" error.
Unfortunately, the script did not always deliver reliable results as I ran it on different hosts. When it did work the script significantly streamlined the setup process. I'll provide steps for both the manual setup and PowerShell script. To download the script, run the following command:
PS C:\> wget -uri https://aka.ms/tp5/Install-ContainerHost -OutFile C:\Install-ContainerHost.ps1
This will download the Install-ContainerHost.ps1 script to your C:\ drive. You can also download it to other directories if you prefer to not run it from the root directory. After the PowerShell setup script has downloaded you can execute it using the following command (remember, if you're running this command on a bare-metal host it you won't be able to easily rollback the changes, so you should backup before executing the command):
PS C:\> powershell.exe -NoProfile -ExecutionPolicy Bypass C:\Install-ContainerHost.ps1
This script takes quite a while to run as it needs to download container images. If the script completes successfully, your system will be container-ready. A virtual switch for the containers will be created. The NanoServer and WindowsServerCore images will be downloaded. Docker will be downloaded and the Docker Daemon service will be created and started. Microsoft provides more details on how to deploy a Windows Server Container host to an existing virtual or physical system here. If the script doesn't complete successfully you can perform a manual setup using the commands in the following sections. If the script completes successfully you can jump down to the "Managing Containers with Docker" section.
Installing OS Images
The previous steps configured the Windows Server host to support containers. However, in order to start creating containers you need a base OS image. OS images have been created for both Windows Server Core and Nano Server. The following PowerShell commands illustrate how to install the ContainerProvider module, which is needed to install OS images, and then use the Find-ContainerImage command to return a list of available images. The following images are included with Windows Server 2016 TP5:
PS C:\> Install-PackageProvider ContainerProvider -ForcePS C:\> Find-ContainerImage
Description: Container OS Image of Windows Se...
Description: Container OS Image of Windows Se...
If you find that either of the container images are missing you can install them using the following Install-ContainerImage commands:
PS C:\> Install-ContainerImage -Name NanoServer
PS C:\> Install-ContainerImage -Name WindowsServerCore
Manually Installing Docker
Once the OS images have been installed, you can install the Docker container management runtime. The Docker runtime is optional, as you can opt to use PowerShell instead. However, if you also plan to use containers on Linux it provides the same functionality and management interface that you get on Windows Server 2016 TP4. First, download docker.exe and place it in the System32 directory on the container host. Next, create a directory named c:\programdata\docker.
You can see how to install Docker in the following listings:
PS C:\> wget https://aka.ms/tp5/dockerd -OutFile $env:SystemRoot\system32\dockerd.exe
PS C:\> New-Item -ItemType File -Path C:\ProgramData\Docker\runDockerDaemon.cmd -Force
The first line downloads the Docker executable while the second creates a new path named c:\programdata\docker and a new file within that path named runDockerDaemon.cmd.
Next, you need to edit the runDockerDaemon.cmd file and add the following text:
if exist %ProgramData%\docker (goto :run)
if exist %certs%\server-cert.pem (if exist %ProgramData%\docker\tag.txt (goto :secure))
if not exist %systemroot%\system32\dockerd.exe (goto :legacy)
dockerd -H npipe://
docker daemon -H npipe://
if not exist %systemroot%\system32\dockerd.exe (goto :legacysecure)
dockerd -H npipe:// -H 0.0.0.0:2376 --tlsverify --tlscacert=%certs%\ca.pem --tlscert=%certs%\server-cert.pem --tlskey=%certs%\server-key.pem
docker daemon -H npipe:// -H 0.0.0.0:2376 --tlsverify --tlscacert=%certs%\ca.pem --tlscert=%certs%\server-cert.pem --tlskey=%certs%\server-key.pem
The runDockerDaemon.cmd file starts the Windows service named Docker Daemon. You need to be sure the value used in the -b parameter matches the name of the virtual switch you're using. The default value used by the setup PowerShell script uses "Virtual Switch."
Next, you need to download and run the nssm.exe program to install the Docker service. The following listing shows how you can download nssm.zip, extract nssm.exe and copy it into the c:\windows\system32 directory:
PS C:\> wget https://nssm.cc/release/nssm-2.24.zip -OutFile $env:ALLUSERSPROFILE\nssm.zip PS C:\> Expand-Archive -Path $env:ALLUSERSPROFILE\nssm.zip $env:ALLUSERSPROFILEPS C:\> Copy-Item $env:ALLUSERSPROFILE\nssm-2.24\win64\nssm.exe $env:SystemRoot\system32
After extracting the nssm.exe file you can run nssm install to configure the Docker service:
PS C:\> start-process nssm install
Nssm.exe provides a simple GUI that enables you to configure a Windows Service. On the Application tab enter the following values:
Path: C:\Windows\System32\cmd.exeStartup Directory: C:\Windows\System32Arguments: /s /c C:\ProgramData\docker\runDockerDaemon.cmd < nulService Name – Docker
On the Details tab you can enter the display name (Docker) and an optional description (such as: The Docker Daemon provides management capabilities of containers for docker clients).
Finally, on the IO tab you can enter the path for the Docker output and error logs:
Output (stdout): C:\ProgramData\docker\daemon.logError (stderr): C:\ProgramData\docker\daemon.log
After filling out the values presented by the nssm.exe program, click the Install Service button to install the Docker service. This will execute the runDockerDaemon.cmd file and then Docker is ready to be used. To start the service run Net Start docker. To stop the service, you can run Net stop Docker followed by net start Docker. To enable remote management open port TCP 2376. If you later want to delete the Docker service, you can use the following command:
C:\sc.exe delete Docker
Microsoft's documentation outlines further details on setting up Windows Server Containers.
Managing Containers with Docker
Docker provides a command-line interface for managing containers. To see all of the commands that Docker supports you can run docker help. To list the existing Docker images on the server, type docker images in the PowerShell console and press ENTER. You should see images called windowsservercore and nanoserver (see Figure 5).
To run an image using Docker, use the following command:
PS C:\docker> docker run -it --name dockerdemo windowsservercore powershell.exe
This will create a new container called dockerdemo. The images will be based on the windowsservercore OS image and it will launch a PowerShell prompt. This really doesn't look much different from a standard PowerShell prompt. However, the container is running in an isolated state on top of the host OS. If you run ipconfig from within the container, you'll see the container's networking configuration (see Figure 6), which includes the container's ipconfig output at the top of the screen and the host's ipconfig output at the bottom of the screen. You'll notice the container has its own IP address and that it's pointing to the host as its default gateway.
Typing exit will leave the interactive shell of the container. In this example the container will continue to exist, but it will be in a stopped state. If you want to re-enter the container you can restart the container and then attach to it:
C:\docker start dockerdemo C:\docker attach dockerdemo
To see the running containers you can use the ps command:
C:\docker ps -a
If you want to delete the container, then you can use the remove command:
C:\docker rm dockerdemo
If you want the container to be automatically removed after you exit it you can add the --rm switch to the docker run command:
PS C:\docker> docker run -it --rm --name dockerdemo windowsservercore powershell.exe
For more detailed information about running Docker containers you can check out the Docker run reference page.
Creating Containers with Docker
You can use the Docker search command to see a list of images available from Docker Hub. The following command shows how you can search for all of the Microsoft container images:
C:\docker search Microsoft
You can retrieve images by using the docker pull command. It's important to note that the windowsservecore OS image must be installed before pulling images dependent on Windows Server Core from Docker Hub. Likewise, the nanoserver OS image is required for any image that's based on Nano Server. For example, here's how you would use the docker pull command to retrieve the microsoft/aspnet image:
C:\docker pull microsoft/aspnet
If you want to create a new container image from a running container, you must first launch the container and then use the docker commit command:
C:\ docker commit dockerdemo dockerdemoimage
Here, dockerdemo is the name of the container that was created in the previous step and dockerdemoimage is the name for the new image. You should note that the image name has to be in lowercase. To later run the image you simply use the docker run command like earlier:
C:\docker run -it --name dockerdemo windowsservercore
If you want to later remove an image you can use the docker rmi command:
C:\docker rmi dockerdemoimage
Wrapping up the Container
The new support for containers in Windows Server 2016 TP4 provides a lightweight mechanism for deploying applications and increasing server density. The option to manage containers with Docker enables you to have a common container management platform for Windows Server Containers and Hyper-V Containers, as well as Linux Containers. Containers won't replace VMs in the near future, but they definitely provide an important new tool in your IT management tool chest.