September 26, 2016 was an important day for both Docker Inc. and Microsoft at Ignite conference in Atlanta. Two week ago, Microsoft finally unveiled the final GA release of Windows Server 2016 which holds plenty of new features such as improved security, productivity, intelligence, cloud, networking tools and not to miss out, a better support for clustering. The major point of attraction was the addition of the Nano Server option, a stripped-down version of the OS for use in the cloud and Microsoft’s System Center 2016 announcement too. A new preview of Azure Stack, targeted to be available in 2017, will allow enterprises to run the core Azure services inside their own data centers.BUT the biggest news was that of Docker Commercial Partnership with Microsoft by extending Docker Engine support on Windows Server 2016 platform. As part of commercial partnership, Microsoft will make the commercially supported Docker Engine available to Windows Server 2016 customer at no additional charge. Essentially, Microsoft will handle most of the basic support and then pass more complicated issues on to Docker Inc.
What does it mean to Windows community?
It means that Windows Server 2016 natively supports Docker containers now on-wards and offers two deployment options - Windows Server Containers and Hyper-V Containers, which offer an additional level of isolation for multi-tenant environments.The extensive partnership integrates across the Microsoft portfolio of developer tools, operating systems and cloud infrastructure including:
- Windows Server 2016
- Visual Studio
- Microsoft Azure
What does it mean to Linux enthusiasts?
In case you are Linux enthusiast like me, you must be curious to know how different does Docker Engine on Windows Server Platform work in comparison to Linux Platform. Under this post, I am going to spend considerable amount of time talking about architectural difference, CLI which works under both the platform and further details about Dockerfile, docker compose and the state of Docker Swarm under Windows Platform.
Let us first talk about architectural difference of Windows containers Vs Linux containers.
Looking at Docker Engine on Linux architecture, sitting on the top are CLI tools like Docker compose, Docker Client CLI, Docker Registry etc. which talks to Docker REST API. Users communicates and interacts with the Docker Engine and in turn, engine communicates with containerd. Containerd spins up runC or other OCI compliant run time to run containers. At the bottom of the architecture, there are underlying kernel features like namespaces which provides isolation and control groups etc. which implements resource accounting and limiting, providing many useful metrics, but they also help ensure that each container gets its fair share of memory, CPU, disk I/O; and, more importantly, that a single container cannot bring the system down by exhausting one of those resources.
Docker Engine on Linux Platform
Under Windows, it's slightly a different story. The architecture looks same for the most of the top level components like same Remote API, same working tools (Docker Compose, Swarm) but as we move down, the architecture looks different. In case you are new to Windows kernel, the Kernel within the Windows is somewhat different than that of Linux because Microsoft takes somewhat different approach to the Kernel’s design. The term “Kernel mode” in Microsoft language refers to not only the Kernel itself but the HAL(hal.dll) and various system services as well. Various managers for Objects, processes, Memory, Security, Cache, Plug in Play (PnP), Power, Configuration and I/O collectively called Windows Executive(ntoskrnl.exe) are available. There is no kernel feature specifically called namespace and cgroup on Windows. Instead, Microsoft team came up with new version of Windows Server 2016 introducing "Compute Service Layer" at OS level which provides namespace, resource control and UFS like capabilities. Also, as you see below, there is NO containerd and runC concept available under Windows Platform. Compute Service Layer provides public interface to container and does the responsibility of managing the containers like starting and stopping containers but it doesn't maintain the state as such. In short, it replaces containerd on windows and abstracts low level capabilities which the kernel provides.
Docker Engine on Windows Platform
The below picture depicts the underlying Windows kernel feature built to support the containers. At the bottom, there is a shared kernel just like that we saw on Linux. The Host User mode talks about the Windows host operating system, primarily the system processes.The most important components are on the left hand side of the picture - System Processes & Application Processes which works differently from Linux prospective. Usually under Linux system, the system call mechanism is documented and guaranteed to be stable across different kernel versions. Windows does not document or even guarantee consistency of the system call mechanism. The only way to make a system call on Windows is to call into
ntdll.dll. Reason of large container size is because of DLLs which are interlinked processes calling each other.
It is important to note that there is no "FROM scratch" in Dockerfile for Windows due to large number of DLLs interlinked system processes to provide the base functionalities. Instead, Microsoft settled down their base images at the following two options:
- microsoft/windowsservercore - basically windows server, .Net 4.5, 9.3 Gigs, large, fully compatible, support Windows existing app
- microsoft/nanoserver - very smaller, ~600MB, no graphic stack, fast, smaller API surface, existing application mighn't be compatible, less memory
A Brief about Windows Namespace:
Under Windows system, there is NO such concept primarily called "namespaces" compared to Linux. But very similar to what namespace does, there is a concept called "Silos" - extension to so called "Windows Job objects." - set of processes which you can assign or limit the resource control. With this, there is an introduction to process namespace, user namespace, object namespace, network namespace etc. Object namespace is a system level namespace hidden from users. Just like Linux, Windows too has \(slash root) at NT level for all the devices, example C:\Windows maps to \DosDevices\C:\Windows, \Device\Tcp in case of networking.
Getting Started with Docker on Windows 2016 Server
Important : You need Windows 2016 Server Evaluation build 14393 or later to taste the newer Docker Engine on Win2k16. If you try to follow the usual Docker installation process on your old Windows 2016 TP5 system, you will get the following error:
Please note that you won't be able to update your TP5 system to Evaluation version to try the newer Docker 1.12.2. One need to install the newer Windows Server 2016 Evaluation version which you can download directly using this link.
Once you have Windows Server 2016 Evaluation versions readily installed, just run the below commands in sequence:
Invoke-WebRequest "https://download.docker.com/components/engine/windows-server/cs-1.12/docker.zip" -OutFile "$env:TEMP\docker.zip" -UseBasicParsing
Expand-Archive -Path "$env:TEMP\docker.zip" -DestinationPath $env:ProgramFiles
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Program Files\Docker", [EnvironmentVariableTarget]::Machine)
The above commands should be enough to get Docker installed on your system without any issue.
Update: 10/11/2016 - Good News ! Windows 2016 Final Release and Nano Server is available under Azure Platform. In case you choose Windows Server 2016 with Container, you need to ensure that the following service is started:
> Start-Service Docker
Now you can search plenty of Windows Dockerized application using the below command:
1. Linux containers doesn't work on Windows Platform.(see below)
2. DTR is still not supported on Windows Platform
3. You can't commit a running container and build image out of it. (This is very much possible on Linux Platform.
Using Dockerfile for MySQL
Building containers using Dockerfile is supported on Windows server platform. Let's pick up a sample MySQL Dockerfile to build up MySQL container. I found it available on some github repository and want to see if Dockerfile is supported or not. The sample Dockerfile looks somewhat like as shown below:
LABEL Description="MySql" Vendor="Oracle" Version="5.6.29"
RUN powershell -Command \
$ErrorActionPreference = 'Stop'; \
Invoke-WebRequest -Method Get -Uri https://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.29-winx64.zip -OutFile c:\mysql.zip ; \
Expand-Archive -Path c:\mysql.zip -DestinationPath c:\ ; \
Remove-Item c:\mysql.zip -Force
RUN SETX /M Path %path%;C:\mysql-5.6.29-winx64\bin
RUN powershell -Command \
$ErrorActionPreference = 'Stop'; \
mysqld.exe --install ; \
Start-Service mysql ; \
Stop-Service mysql ; \
RUN type NUL > C:\mysql-5.6.29-winx64\bin\foo.mysql
RUN echo UPDATE user SET Password=PASSWORD('mysql123') WHERE User='root'; FLUSH PRIVILEGES; .> C:\mysql-5.6.29-winx64\bin\foo.mysql
RUN mysql -u root mysql < C:\mysql-5.6.29-winx64\bin\foo.mysql
This just brings up the MySQL image perfectly. I had my own version of MySQL Dockerized image available which is still under progress. I still need to populate the Docker image details.
Does Docker Engine on Windows support Swarm Mode?
Not Yet. Docker Engine on Windows Platform is still young. There has been number of contributions flowing in from Windows and Linux enthusiasts to build Windows containers.
In the future post, I will be talking about how to get simple application like wordpress up and running using Docker-compose.
[clickandtweet handle="@ajeetsraina" hashtag="#docker, #windows" related="@docker" layout="" position=""]A Comparative Study of Docker Engine on Windows Server Vs Linux Platform[/clickandtweet]