Install Docker on Windows Server 2016 using DSC

Windows Server 2016 is now GA and it contains some pretty exciting stuff. Chief among them for me is support for containers by way of Docker. So, one of the first things I did was start installing Windows Server 2016 VM’s (Server Core and Nano Server naturally) and installing Docker on them so I could begin experimenting with Docker Swarms and other cool stuff.

Edit: If you’re looking for a DSC configuration for setting up Docker on a Windows 10 Anniversary Edition machine, see the Windows 10 AE section below.

At first I started using the standard manual instructions provided by Docker, but this doesn’t really suit any kind of automation or infrastructure as code methodology. This of course was a good job for PowerShell Desired State Configuration (DSC).

So, what I did was put together a basic DSC config that I could load into a DSC Pull Server and build out lots of Docker nodes quickly and easily. This worked really nicely for me to build out lots of Windows Server 2016 Container hosts in very short order:

ss_dockerdsc_installing

If you don’t have a DSC Pull server or you just want a simple script that you can use to quickly configure a Windows Server 2016 (Core or Core with GUI only) then read on.

Note: This script and process is really just an example of how you can configure Docker Container hosts with DSC. In a real production environment you would probably want to use a DSC Pull Server.

Get it Done

Edit: After a suggestion from Michael Friis (@friism) I have uploaded the script to the PowerShell Gallery and provided a simplified method of installation. The steps could be simplified even further into a single line, but I’ve kept them separate to show the process.

Using PowerShell Gallery

On a Windows Server 2016 Server Core or Windows Server 2016 Server Core with GUI server:

  1. Log on as a user with Local Administrator privileges.
  2. Start an Administrator PowerShell console – if you’re using Server Core just enter PowerShell at the command prompt:ss_dockerdsc_console
  3. Install the Install-DockerOnWS2016UsingDSC.ps1 script from the PowerShell Gallery using this command:

    You may be asked to confirm installation of these modules, answer yes to any confirmations.
    ss_dockerdsc_consolegetscript
  4. Run the Install-DockerOnWS2016UsingDSC.ps1 script using:

    ss_dockerdsc_consolerunscriptfromgallery

The script will run and reboot the server once. Not long after the reboot the Docker service will start up and you can get working with containers:

ss_dockerdsc_consoledockerdetails

You’re now ready to start working with Containers.

The Older Method (without PowerShell Gallery)

On a Windows Server 2016 Server Core or Windows Server 2016 Server Core with GUI server:

  1. Log on as a user with Local Administrator privileges.
  2. Start an Administrator PowerShell console – if you’re using Server Core just enter PowerShell at the command prompt:ss_dockerdsc_console
  3. Install the DSC Resources required for the DSC configuration by executing these commands:

    You may be asked to confirm installation of these modules, answer yes to any confirmations.
    ss_dockerdsc_consoleinstallresources
  4. Download the Docker installation DSC script by executing this command:

    ss_dockerdsc_consoledownloadscript
  5. Run the Docker installation DSC script by executing this command:

    ss_dockerdsc_consolerunscript

The script will run and reboot the server once. Not long after the reboot the Docker service will start up and you can get working with containers:

ss_dockerdsc_consoledockerdetails

You’re now ready to start working with Containers.

What the Script Does

In case you’re interested in what the script actually contains, here are the components:

  1. Configuration ContainerHostDsc – the DSC configuration that configures the node as a Docker Container host.
  2. Configuration ConfigureLCM – the LCM meta configuration that sets Push Mode, allows the LCM to reboot the node if required and configures ApplyAndAutoCorrect mode.
  3. ConfigData – a ConfigData object that contains the list of node names to apply this DSC Configuration to – in this case LocalHost.
  4. ConfigureLCM – the call to the Configuration ConfigureLCM to compile the LCM meta configuration MOF file.
  5. Set-DscLocalConfigurationManager – this applies the compiled LCM meta configuration MOF file to LocalHost to configure the LCM.
  6. ContainerHostDsc – the call to the Configuration ContainerHostDsc to compile the DSC MOF file.
  7. Start-DSCConfiguration – this command starts the LCM applying the DSC MOF file produces by the ContainerHostDsc.

The complete script can be found here. Feel free to use this code in anyway that makes sense to you.

What About Windows 10 AE?

If you’re looking for a DSC configuration that does the same thing for Windows 10 Anniversary edition, Ben Gelens (@bgelens) has written an awesome DSC config that will do the trick. Check it out here.

 

Happy containering!

Advertisements

Failed to Start Docker Service on Windows 10 AE

So, pretty much the first thing I did when the Windows 10 Anniversary Edition was installed onto my primary development machine was to installer the Windows Container Service and Docker on it.

I used the Windows Containers on Windows 10 Quick start guide to perform the installation. This is the same method I’d been using on my secondary development machine (running Insider Preview builds) since it was first available in build 14372.

Note: The Windows Containers on Windows 10 Quick Start guide doesn’t mention the Anniversary Edition specifically, but the method still works.

Unfortunately though, this time it didn’t work. When I attempted to start the Docker Service I received the error:

start-service : Failed to start service 'Docker Engine (docker)'.

ss_docker_startserviceerror

So, after a bit of digging around I found the following error in the Windows Event Log in the Application logs:

ss_docker_startserviceerror_eventlog

Basically what this was telling me was that the Docker Daemon couldn’t create the new virtual network adapter that it needed – because it already existed. So a quick run of Get-NetAdapter and I found that the docker adapter “vEthernet (HNS Internal)” already existed:

ss_docker_startserviceerror_eventlog

So what I needed to do was uninstall this adapter so that the Docker Service could recreate it. I’m not actually aware of a command line method of doing (except for using DevCon) so I had to resort to using Device Manager:

ss_docker_startservice_uninstalldevice

You’ll need to use the output of the Get-NetAdapter to find he right adapter uninstall. Once it has been uninstalled you should be able to start the service again:

ss_docker_startservice_dockerstarts

This time the service should start successfully. A quick call to docker ps shows that the container service is indeed working. So now I can get onto the process pulling down the base container images.

Hopefully if anyone else runs into this problem in Windows 10 AE this will help them resolve it.

 

 

 

Detatch from a Docker Container without Stopping It

Saturday morning Docker fun times (still only on Windows Server Core) – here is something I found out that might be useful. It is in the Docker documentation but it is not mentioned in the Microsoft container documentation.

Once you have attached to a Docker Container via a CMD console typing exit at the console detatches from the container and Stops it. This is not usually what I want to do. To detatch from the container without stopping it press CTRL+P followed by CTRL+Q.

The container is still running after being detached.

The container is still running after being detached.

Note: This only applies to Docker Containers that have been attached to via docker attach or docker run. Windows Server Containers that have been connected to via Enter-PSSession can be exited using the Exit command.

Well that is enough for a Saturday morning.

How To use Containers on Windows Nano Server

Edit: I wrote this article when examining containers on Windows Nano Server TP3which wasn’t in a working state. I have not yet had a chance to fully examine containers on Windows Nano Server TP4, but when I get a spare day hours I will no doubt deep dive into it.

If you’re looking for instructions on installing and using containers on Windows Nano Server TP4, start here.

These instructions are more focused on setting up a container host on Windows Server Core TP4, but I have managed to get them working on Windows Nano Server TP4 just fine:

ss_nano_containerhostworking

I do plan to document this process over the next week or so.


 

You’d be forgiven for believing that it was just a simple click of a button (or addition of a package) to get Docker Containers working on a shiny new Windows Nano Server TP3 install. That is what I thought too. But after careful examination of the available documentation I found that there isn’t much information on running actually getting containers working on Nano Server. Sure, there is lots of information on running it on a full or core version of WIndows Server TP3, but Nano is lacking. So, because I’m a bit obsessive I decided I’d have a try and adapting the standard installation process.

Edit: Initially I had a bit of success, but I’ve run into some rather stop dead issues that I haven’t been able to resolve (see later on in this post).

I have continued the investigation here with a much more in depth look at the issues.

tl;dr: Containers on Windows Server Nano 2016 TP3 does not work yet! The Base OS WIM file for Windows Server Nano is required, but has not been provided.

Problems with the Standard Containers Install Script

First up I grabbed a copy of this script from Microsoft which is what is used to install containers on a full Windows Server 2016 install. I took a look at it and identified the things that wouldn’t work on a Nano Server 2016 install. This is what I found:

  1. The script can optionally configure a NAT switch – this requires the NetNat PS module which isn’t available on Nano.
  2. The script will install a VM Switch – therefore the Compute package is required to be installed on the Nano Server (the Compute package contains the Hyper-V components).
  3. The script can download various files from the internet (using the alias wget). Wget and Invoke-WebRequest are not available on Nano Server – so we’ll need to download the files to another machine and pre-copy them to the Nano Server.
  4. The Expand-Archive is used to extract the NSSM executable, but this cmdlet is not available on Nano Server either – so we’ll need to extract the NSSM.exe on another machine and copy it to the server.

The Process of Installing a Container Host

The process of actually installing a Container Host in Windows Nano Server is as follows:

  1. Create a Nano Server VHDx with the packages Guest, OEM-Drivers, Compute and Containers.
  2. Create a new VM booting from the VHDx – this is our Container Host.
  3. Upload a Base OS WIM file to the Container Host containing that will be used to create new containers.
  4. Upload Docker.exe to c:\windows\system32\ on the Container Host.
  5. Upload NSSM.exe to c:\windows\system32\ on the Container Host – this is used to create and run the Docker Service.
  6. Run the installation script on the Container Host – this will install the networking components and configure the Docker service as well as create the container OS image.
  7. Create a Container!

In theory the Container Host is now ready to go!

What is Required to build a Nano Server Container Host

A bit of experience with PowerShell is a good help here!

So, to create a Nano Server Container Host you’ll need a few things:

  1. A machine that can run Generation 2 Hyper-V machines (Gen 1 will probably work but I’m using Gen 2) – this will host your Nano Server. This machine must also be running PowerShell 5.0 (I’m using some PS5.0 only cmdlets)!
  2. A copy of the Windows Server 2016 TP 3 ISO from here.
  3. A working folder (I used D:\Temp) where you’ll put all the scripts and other files etc.
  4. The scripts (I’ll provide them all in a zip file), but they are:
    1. New-ContainerHostNano.ps1 – this will do everything and is the only script you’ll run.
    2. Install-ContainerHostNano.ps1 – this is the script that gets automatically run on the Container Host. It is a version of the Microsoft one from here that I have adjusted to work with Nano Server.
    3. New-NanoServerVHD.ps1 – this is a script I wrote a while back to create Nano Server VHDx files (see this post for more details).
    4. Convert-WindowsImage.ps1 – this script is required by New-NanoServerVHD.ps1 and is available on Microsoft Script Center.

How Can I use all This?

I haven’t really finished implementing or testing these scripts and I am encountering a problem creating the VM Switch on the Nano Server, but if you’re interested you can get a hold of the scripts in my GitHub repository.

To use them:

  1. Create a working folder (I used d:\temp).
  2. Download the four PS1 scripts from the GitHub repository to the working folder.
  3. Download the Windows Server 2016 TP3 ISO from here and put it in the working folder.
  4. Download the Base OS Container Image from here (3.5GB download) and put it in the working folder.
  5. Edit the New-ContainerHostNano.ps1 file in the working folder and customize the variables at the top to suit your paths and such – fairly self explanatory.
  6. In an Administrative PowerShell run the New-ContainerHostNano.ps1 file.

Please note: This is a work in progress. There are definitely some bugs in it:

  1. An error is occurring when trying to create the VM Switch in DHCP mode or NAT mode.
  2. If using NAT mode the NAT module isn’t included in Nano Server so although the VM switch gets created the NAT Network adapter can’t be created.
  3. NSSM isn’t creating the Docker Service – which may just be an issue with running the PowerShell installation script remotely.

None of the above will stop containers being created though. The containers might not be able to communicate with the world via networking and the Docker management engine might not work, but in theory the containers should still work (at least that is my understanding).

The BIG Problem

Any container that you create requires a WIM file that contains the container base OS image that container will use. Microsoft has so far only provided a base WIM file for WIndows Server 2016 Core installations – they haven’t provided a container base OS Image for Windows Server 2016 Nano yet. You can download the Core one from here (3.5GB download).

If you try to use the NanoServer.WIM file from the Windows Server 2016 ISO as the container base OS image you can’t even create the container at all.

I did try putting the Core WIM file downloaded above onto the Nano Server. I could then create a container OK, but an error would occur starting it up:

Nope - can't use the Core WIM with a Nano Server Container Host!

Nope – can’t use the Core WIM with a Nano Server Container Host!

Update 2015-10-29: There is a new video available online from Microsoft of Mark Russinovich (Azure CTO) doing a container demonstration using a Nano Server. It clearly shows that the NanoServer Base Container Image does exist. So perhaps we’ll see this in the TP4 release.

The video can be seen here.

Feel free to let me know if you can solve any of these issues! Any help is appreciated. I’ll continue to work on this and post any additional results.