Demystifying Docker Containers Support on Windows 10 and Windows Server 2016
Both my colleague Kendall Roden and myself were recently taking a deep dive into docker containers support on Windows 10 and Windows Server 2016. We knew that we could install “Docker Desktop” to add support for Docker, but as we dug deeper we found out that there is more to it than simply installing “Docker Desktop”. Basically the experience on Windows 10 was tailored towards developers whereas the experience on Windows Server 2016 was tailored towards production. This had several implications ranging from the tools that can be used all the way to the capabilities available on each platform. This blog post is our attempt to demystify the differences in the experience on both platforms and along the way uncover some of the driving technologies on Windows 10 and Windows Server 2016 that makes docker support even possible in the first place.
It’s no secret by now that “Docker Desktop” is the go to tool for adding support for docker containers on Windows 10. Once you install the tool you will notice you get two key components which allow you to run both Linux based containers as well as Windows based containers. The first piece is a Linux Hyper-V VM (called MobyLinuxVM) which gets created automatically after installing “Docker Desktop” tool. This is required since containers share a kernel with the container host, thus running Linux containers directly on Windows isn’t an option. As for Windows containers they do not require a VM as the kernel of the host OS (Windows 10 or Windows Server 2016) can be used.
The other key feature that gets provided is the ability to switch between Linux mode as well as Windows mode. This can be achieved by clicking on the docker icon on your Windows 10 machine status bar and switching between the modes there.
Whereas “Docker Desktop” allowed us to run both Linux based containers as well as Windows based containers, it only allowed running one type of containers at a time but not both. This can be problematic if for example you had an application which contained a Windows based container (e.g. frontend using Asp.Net 4.x) as well as a Linux based container (restful api built with NodeJS with Express running on top of it). You cannot run both containers at the same time and as a result you cannot test a fully functional application in this scenario. Fortunately, “Docker Desktop” now has an experimental feature (starting with Docker Engine version 18.02) which allows us to run both types of containers at the same time (make sure you are in windows mode when you enable this feature).
At this point you will always be in Windows mode, but having the experimental feature enabled allows you to run both Windows and Linux based containers at the same time without the need for switching modes anymore. Once we did that we noticed an interesting behavior that cropped up. Basically, the MobyLinuxVM was not being utilized anymore (we were able to confirm that by monitoring the cpu utilization and later stopping it). At first we thought there was some Vodoo happening here, but it turns out it was no Voodoo but rather the experimental feature was enabling a feature called Linux containers with Hyper-V Isolation (LCOW). Linux containers with Hyper-V isolation run each Linux container (LCOW) in an optimized Linux VM with just enough OS to run containers. In contrast to the Moby VM approach, each LCOW has its own kernel and its own VM sandbox. They’re also managed by Docker on Windows directly. Taking a closer look at how container management differs between the Moby VM approach and LCOW, in the LCOW model container management stays on Windows and each LCOW management happens via GRPC and containerd. This means the Linux distro containers use for LCOW can have a much smaller inventory. Right now, using LinuxKit for the optimized distro containers use, but other projects like Kata are building similar highly-tuned Linux distros (Clear Linux) as well. For more information about how it works in details you can follow this link.
So after understanding the two options that are available for running a linux based container on Windows 10 we shifted our focus to Windows containers. It turns out that Windows based containers(nanoserver and servercore at the time of writing this post) could also run using two options. The first option was what we expected and that is running containers in a process while sharing the host OS kernel. The second option uses the same Hyper-V Isolation technology that is used to run the Linux containers outside the Moby VM. What was even more interesting is that the only option currently available to run Windows containers on Windows 10 is the Hyper-V Isolation. We confirmed that by trying to run the windows container with the --isolation=process under Windows and we got the following error:
In order to confirm that the Windows container was running in Hyper-V Isolation mode we utilized a tool called Host Compute Service (HCS). HCS is a low level container management API in Hyper-V called the Host Compute Service (HCS). Executing the following command hcsdiag list showed the windows container in Hyper-V Isolation mode.
At this point we could have called it a day, but we were not done yet! Remember we mentioned early in this post that “Docker Desktop” is meant for development purposes and hence its only recommended to install it on your Windows 10 machine. Windows Server 2016 installs Docker Enterprise Edition(EE) as a feature. In addition, we found out that starting with Windows Server version 1709 Microsoft worked closely with Docker to bring support for Linux containers on Windows with the LinuxKit project. You can read more about this collaboration here.
There you go you now know how to run both Windows and Linux based containers on both Windows 10 and Windows Server 2016. We would like to point out that this is still an experimental feature and may still change in the future so it’s recommended that you keep a close eye on the updates for LCOW on both platforms.