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!

NanoServer Container Base Image – It does Exist…Somewhere!

A really interesting video from Microsoft was just released with Mark Russinovich (CTO of Azure if you don’t already know) demonstrating Windows Server Containers. What is really interesting about this demo is that he is demonstrating containers using a Windows NanoServer Base Image:

Nano Server Containers Base Image - it does exist.

Nano Server Containers Base Image – it does exist.

If you’ve read any of my previous posts here and here you’ll know I spent quite some time looking at this and trying to get it going with TP3. I deduced it was not possible yet without the Windows NanoServer Base Image for containers – which had not been provided by Microsoft.

Other eagle eyed viewers will also note that he appears to be running a Nano Server container on a Full Server container host which I didn’t actually think was possible. From what I originally understood about containers is that you could only instantiate a container using a base container image matching the version of the OS the container host used. E.g. You can not instantiate a Server Core container on a NanoServer container host – I confirmed this was the case in TP3. But perhaps I misunderstood, or perhaps containers can be instantiated on “up” version container hosts but not “down” version.

Edit: Actually on further examination he is remoting into a different server that is acting as a Container Host (10.205.158.127). So I can’t assume that this remote host is a Full Server – it could well be a NanoServer. So the above paragraph isn’t relevant.

I also notice that he demos Hyper-V Containers, which as far as I am aware aren’t working on TP3. So this would indicate a more recent build than TP3.

So perhaps we’ll see this image being made available in the Windows Server 2016 TP4 release?

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.

Docker and Containers on Nano Server Continued

This is a continuation of my investigation of how to get Containers and also possibly the Docker engine running on Windows Server Nano 2016 TP 3. The initial investigation into this can be found here: How to use Containers on Windows Nano Server.

This post is mainly documenting the process of manually creating containers on Windows Nano Server 2016 TP3 as well as some additional details about what I have managed to find out. The documentation on Windows Server Containers from Microsoft is relatively thin at the moment (not surprising – this is very much in technical preview) and so a lot of the information here is speculation on my part. Still, it might be useful to get an idea of how things eventually will work. But of course a good deal of it could change in the near future. This information is really to help me get my head around the concepts and how it will work, but it might be useful for others.

Step 1 – Create a Nano Server Virtual Machine

Anyone who has played around with Nano Server should already be very familiar with this step. The only thing to remember is that the following packages must be included in the VHDx:

  1. Guest – All Nano Server VHDx files running as  VM should have this package. If you’re installing Nano Server onto bare metal you won’t need this.
  2. Compute – Includes the Nano Server Hyper-V components. Required because Containers use Hyper-V networking and are a form of Virtualization.
  3. OEM-Drivers – Not strictly required but I tend to include it anyway.
  4. Containers – This package provides the core of Windows Server Containers.

If you’re unfamiliar with creating a Nano Server VHDx, please see this post.

Step 2 – Configure the Container Host Networking

Any container that needs to be connected to a network (most of them usually) will need to connect to a Hyper-V Virtual Switch configured on this Container Host. There are two virtual switch types that can be configured for this purpose:

  1. NAT – This seems to be a new switch type in Windows Server 2016 that causes performs some kind of NAT on the connected adapters.
  2. DHCP – this is actually just a standard External switch with a connection to a physical network adapter on the Container Host.

The installation script normally performs one of the above depending on which option you select. However on Nano Server both of these processes fail:

NAT

Creating a NAT VM Switch on Nano Server actually works. But the command to create a NAT Network connection to the VM Switch fails because the NETNAT module is not available on Nano Server.

DHCP

Creating a standard External VM Switch on Nano Server

Creating a DHCP/External VM Switch on Nano Server just fails with a cryptic error message. The same error occurs when creating a Private or Internal VM Switch, so I expect Hyper-V on Nano Server isn’t working so well (or at all). Not much point pursuing this method of networking.

Step 3 – Install a Base OS Image from a WIM File

Every container you create requires a Base OS Image. This Base OS Image contains all the operating system files and registry settings for the OS a container uses. Windows Server Containers expects to be provided with at least one Base OS Image in the form of a WIM file. You can’t create a container without one of these. At this point I am unsure if the WIM file that Windows Server Containers will use is a customized version of the WIM file provided with an OS or if it is standard.

During an installation of Windows Server Containers onto a Windows Server Core operating system, the process automatically downloads a WIM file that is used as the Base OS Image.

To install a Base OS Image from a WIM File to the Container Host using the PowerShell function:

Install-ContainerOSImage -WimPath CoreServer.wim -Verbose

Installing a Base OS Image

This function does several things:

  1. Creates a new folder in c:\programdata\microsoft\windows\images with Canonical Name of the new Base OS Image:
    Contents of the Images folder
  2. Inside the Canonical Name folder a subfolder called files is created where the Base OS Image file is extracted to:The contents of an Image Files
  3. Another subfolder called hives is also created in the Canonical Name folder which contains the default registry hives for the Base OS Image:
    The Image Registry Hives
  4. Two additional files are created in the Canonical Name folder that contain metadata about the image:
    Metadata.json
    Version.wcxImage Metadata
  5. Adds the Base OS Image into the list of Image Containers that are available to create new Containers from:
    All Base OS Images installed

I have tried using the Install.wim from the ISO, the NanoServer.wim from the ISO and the Core.wim downloaded using the Core Edition Containers install script. Also note, the INSTALL.WIM file on the TP3 ISO still refers to Windows Server 2012 R2 SERVERSTANDARDCORE (I double checked this and you can confirm by the Version number in the OS Image).

The Test-ContainerImage cmdlet can be used to identify “problems” with container images:

Testing Containers

None of the container images report any problems which is nice to know.

Step 4 – Create a Container

This is obviously where things should start to get exciting! The next step is to create a shiny new container using one of our Base OS Images. However, if you try and create a new container at this point a cryptic error message will occur:

New Container? Nope!

I don’t know what causes this, but if you reboot your Nano Server VM the error goes away and you should be able to successfully create the container:

First Container - making progress

Unfortunately only the Base OS Image downloaded from Microsoft and used with Containers for Windows Server 2016 Core results in a valid Container. So it would seem there are some things that are done to a WIM file to make it able to be Containerized (is that a word?).

Step 5 – Start the Container

I’m not holding my breath here. This is what happens when the container is started:

Starting up the Container - nope!

Looking closely at the text of the error it would appear that there was a mismatch between the Container Host OS version and that of the Base OS version that the container was using. This is probably because the Container Host is a Nano Server and the Base OS that was downloaded was for a Core Server.

Next Steps

It would seem at this point we have to wait for Microsoft to provide a Base OS file for Nano Server and also fix the Virtual Switch issues with Nano Server before any further progress can be made experimenting with Containers on Nano Server.

However, it may still be possible to get the Docker Engine working under Nano Server and see if that offers any more information. So that will be what I’ll look into next.

Also, it is interesting to dig around into the files that are created when the new container was created:

Files Created with a Container

When a container is created the container files are stored in the C:\ProgramData\Microsoft\Windows\Hyper-V\containers folder. Unfortunately the files all binary so we aren’t able to dig around in them to glean any other information.

Well, that is enough for today.

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.

PowerShell CmdLets available in the Containers Module on a Nano Server

Just a Monday morning quickie:

Here is a list of all the cmdlets available in the PowerShell containers module on a Nano Server with the containers package installed:

Containers - the next big thing!

Containers – the next big thing!

And here is the text version:

Function        Install-ContainerOSImage                           1.0.0.0    Containers
Function        Uninstall-ContainerOSImage                         1.0.0.0    Containers
Cmdlet          Add-ContainerNetworkAdapter                        1.0.0.0    Containers
Cmdlet          Connect-ContainerNetworkAdapter                    1.0.0.0    Containers
Cmdlet          Disconnect-ContainerNetworkAdapter                 1.0.0.0    Containers
Cmdlet          Export-ContainerImage                              1.0.0.0    Containers
Cmdlet          Get-Container                                      1.0.0.0    Containers
Cmdlet          Get-ContainerHost                                  1.0.0.0    Containers
Cmdlet          Get-ContainerImage                                 1.0.0.0    Containers
Cmdlet          Get-ContainerNetworkAdapter                        1.0.0.0    Containers
Cmdlet          Import-ContainerImage                              1.0.0.0    Containers
Cmdlet          Move-ContainerImageRepository                      1.0.0.0    Containers
Cmdlet          New-Container                                      1.0.0.0    Containers
Cmdlet          New-ContainerImage                                 1.0.0.0    Containers
Cmdlet          Remove-Container                                   1.0.0.0    Containers
Cmdlet          Remove-ContainerImage                              1.0.0.0    Containers
Cmdlet          Remove-ContainerNetworkAdapter                     1.0.0.0    Containers
Cmdlet          Set-ContainerNetworkAdapter                        1.0.0.0    Containers
Cmdlet          Start-Container                                    1.0.0.0    Containers
Cmdlet          Stop-Container                                     1.0.0.0    Containers
Cmdlet          Test-ContainerImage                                1.0.0.0    Containers