- First Part – The basics: the basic principles of how container virtualization is implemented in Windows Server 2016 operating system.
- Second part – Up and Running: creating and managing Windows Server Containers using Docker.
- Third part – Into your Stride Working with Windows Containers and Docker
- Fourth part -- Save the Container Data
Introduction
Windows containers will revolutionize virtualization and the DevOps process.
With Windows Server 2016, Microsoft introduces the new feature called Windows Containers. Organizations that upgrade their servers to this new operating system will then be able to use containers right through from development to the production environment.
Robert Sheldon wrote a great article about Windows containers on Simple Talk: https://www.simple-talk.com/cloud/platform-as-a-service/windows-containers-and-docker/. We will not dig deep once again into the concept of containers, but I will explain in this series how to create, run, convert and manage your Windows Containers.
Windows Containers Fundamentals
Before starting with the practical side of Windows Containers, I ought to quickly cover the basics about this new feature.
Containers wrap software up within in a complete file system that contains everything it needs to run: code, runtime, system tools and system libraries. This guarantees that it will always run the same, regardless of the environment it is running within. To achieve this goal, Windows uses namespace isolation, resource control, and process-isolation technologies to restrict the files, network ports, and running processes that each container can access, so that applications running in containers can’t interact or see other applications running in the host OS or in other containers.
Virtual Machines Vs Containers
A Virtual machine is standalone and has its own operating system, its own applications and its own resources (memory, CPU and so on). The following schema shows three VMs hosted on the same physical host. Each virtual machine uses its own OS, libraries, etc. In consequence, they occupy significant amounts of memory.
Quite often, developers need to test applications with different versions very quickly. Then they must ask to the IT Ops team to deploy one or many machines (Virtual or Physical): It is a time consuming process. VMs also consume considerable resources such as memory and storage space. That’s the reason why containers are amazingly useful for the DevOps process:
Containers, in contrast, do not contain any operating system, so they take up fewer resources than virtual machines on the physical host. Containers simply share the host operating system, including the kernel and libraries, so they don’t need to boot a full OS.
In summary, the benefits of Windows containers are that:
- When you deploy a container in a production environment, the rollback process is very simple. You just need to modify the deployment script and redeploy the Container image. Just imagine the rollback process with virtual machines? Well, you must rebuild the entire machine (or revert to the previous snapshot/backup).
- Startup time for a Windows container is faster than a VM.
- The small footprint benefits cloud-based scenarios
To finish, the container philosophy is “one service per container”
Windows Server Containers Vs Hyper-V Containers
Microsoft includes two different types of container. The first type is based on the Windows Server Core image and is called a Windows Server Container. The second one is called a Hyper-V Container and is based on the Windows Nano Server image. Hyper-V Containers expand on the isolation that is provided by Windows Server Containers by running each container in a highly-optimized virtual machine, so that they provide a full secure isolation. The kernel of the container host is not shared with other Hyper-V Containers. If all the code running on a host is trusted, then the isolation provided by Windows Containers is likely to be adequate. But if we don’t trust the code, then Hyper-V Containers provide the same level of isolation as virtual machines, but with many of the benefits of standard containers.
Please note that Hyper-V containers are only managed by Docker, while Hyper-V Virtual Machines are managed by traditional tools such as Hyper-V Manager. In practice, booting Hyper-V containers takes longer than Windows Server Containers but both are much faster than a VM with a full OS (even on Nano Server).
Docker
In October 2014, Microsoft Corp and Docker announced a strategic partnership to bring the agility, portability, and security benefits of the Docker platform to Windows Server.
Windows Server 2016 Containers, powered by Docker Engine
It is essential to understand that Windows Server 2016 can’t run Linux containers in Docker format but only Windows containers. Why? Because Linux containers require the Linux APIs from the host kernel and Windows Server Containers require the Windows APIs of a host Windows kernel.
However, the process of managing Linux and Windows containers are strictly identical. The following schema describe the Docker platform:
Here is a summary of Windows Containers jargon with their meaning:
- Container Host: Physical or Virtual computer system configured with the Windows Container feature.
- Container Image: A container image contains the base operating system, application, and all the application dependencies that are needed to quickly deploy a container.
- Container OS Image: The container OS image is the operating system environment.
- Container Registry: Container images are stored in a container registry, and can be downloaded on demand. It is a place where container images are published. A registry can be remote or on-premises.
- Docker Engine: It is the core of the Docker platform. It is a lightweight container runtime that builds and runs your container.
- Docker file: Docker files are used by developers to build and automate the creation of container images. With a Docker file, the Docker daemon can automatically build a container image.
Docker provides a central repository called Docker Hub (https://hub.docker.com/), the public containerized-application registry that Docker maintains. Container Images can be published directly on this repository to be shared with the Docker community. There are already many images hosted on the Docker Hub. For example:
- SQL
- WordPress
- IIS
- …
You can run a private repository on-premise. Microsoft has its own public and official repository available via this URL: https://hub.docker.com/u/microsoft/
Windows Containers in practice
Before deploying Windows Containers, you must prepare your environment with some prerequisites. To do that, you can use a physical or virtual machine, it’s up to you. In my case, I use a VM with the following characteristics:
- A system running Windows Server 2016 (or Windows 10). It is the most important prerequisite. I advise you to work with the Datacenter version because of licensing (more information at the end of the article). You can choose to use Windows Server Core for your container host as opposed to the version of windows which includes a full UI.
- Administrator permissions on the container host
- Minimum free drive space to store images and deployment scripts
- Your server must be up-to-date
OK, let’s start by installing the Windows Containers feature on the container host. To perform this task, run the following PowerShell command:
1 2 3 4 5 6 |
PS C:\Users\Administrator> Install-WindowsFeature Containers Success Restart Needed Exit Code Feature Result ------- -------------- --------- -------------- True Yes SuccessRest... {Containers} WARNING: You must restart this server to finish the installation process. |
You must restart to apply changes via the Restart-Computer cmdlet:
1 |
PS C:\Users\Administrator> Restart-Computer |
Then check that the new feature is enabled:
1 2 3 4 5 |
PS C:\Users\Administrator> Get-WindowsFeature containers Display Name Name Install State ------------ ---- ------------- [X] Containers Containers Installed |
Windows containers being intimately linked to Docker; you must install Docker Engine on the container host. To achieve this goal, you have two possibilities:
The first one is to deploy Docker from the PSGallery repository:
1 2 3 4 5 6 7 8 9 |
PS C:\Users\Administrator> Install-Module -Name DockerMsftProvider -Repository PSGallery -Force NuGet provider is required to continue PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact with NuGet-based repositories. The NuGet provider must be available in 'C:\Program Files\PackageManagement\ProviderAssemblies' or 'C:\Users\Administrator\AppData\Local\PackageManagement\ProviderAssemblies'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to install and import the NuGet provider now? [Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): |
If you need more details about managing packages with PowerShell, I forward you to this article: https://www.simple-talk.com/sysadmin/powershell/managing-packages-using-windows-powershell/
1 2 3 4 5 6 7 8 9 10 11 12 13 |
PS C:\Users\Administrator> Install-Package -Name docker -ProviderName DockerMsftProvider The package(s) come(s) from a package source that is not marked as trusted. Are you sure you want to install software from 'DockerDefault'? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): Y Install-Package : KB3176936 or later is required for docker to work At line:1 char:1 + Install-Package -Name docker -ProviderName DockerMsftProvider + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (Microsoft.Power....InstallPackage:InstallPackage) [Install-Package], Exception + FullyQualifiedErrorId : RequiredWindowsUpdateNotInstalled,Install-Package,Microsoft.PowerShell.PackageManagement .Cmdlets.InstallPackage |
Docker for Windows Server 2016 requires update “KB3176936”. You can download it from the Windows Update Website and then install manually:
http://www.catalog.update.microsoft.com/search.aspx?q=kb3176936
Or you can perform this task using sconfig utility. Then, choose the number 6:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
=============================================================================== Server Configuration =============================================================================== 1) Domain/Workgroup: Domain: get-cmd.Local 2) Computer Name: SRV1 3) Add Local Administrator 4) Configure Remote Management Enabled 5) Windows Update Settings: DownloadOnly 6) Download and Install Updates 7) Remote Desktop: Enabled (more secure clients only) 8) Network Settings 9) Date and Time 10) Telemetry settings Basic 11) Windows Activation 12) Log Off User 13) Restart Server 14) Shut Down Server 15) Exit to Command Line |
Windows will download and install updates:
1 2 3 4 5 6 7 8 |
Microsoft (R) Windows Script Host Version 5.812 Copyright (C) Microsoft Corporation. All rights reserved. Search for for (A)ll updates or (R)ecommended updates only? a Searching for all applicable updates... Downloading updates... |
The second way is to install the development Docker version, in order to have the latest features. You must download Docker directly from the official website. Use the Invoke-WebRequest cmdlet:
1 |
PS > Invoke-WebRequest "https://master.dockerproject.org/windows/amd64/docker-1.14.0-dev.zip" -OutFile "$env:TEMP\docker.zip" –UseBasicParsing |
Next, extract the archive via the Expand-Archive cmdlet:
1 |
PS > Expand-Archive -Path "$env:TEMP\docker.zip" -DestinationPath $env:ProgramFiles |
Now, you can create an environment variable:
1 2 3 |
PS > $env:path += ";$env:ProgramFiles\Docker" PS > $existingMachinePath = [Environment]::GetEnvironmentVariable("Path",[System.EnvironmentVariableTarget]::Machine) PS > [Environment]::SetEnvironmentVariable("Path", $existingMachinePath + ";$env:ProgramFiles\Docker", [EnvironmentVariableTarget]::Machine) |
To finish, install Docker as a Windows service. So run the following command to register dockerd.exe:
1 |
PS > dockerd --register-service |
Once installed, the service can be started:
1 2 3 4 5 6 7 8 |
PS > Start-Service Docker WARNING: Waiting for service 'Docker Engine (Docker)' to start... PS > Get-Service -name "docker*" Status Name DisplayName ------ ---- ----------- Running docker Docker Engine |
To display Docker information, run the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
PS C:\> docker info Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 0 Server Version: 1.14.0-dev Storage Driver: windowsfilter Windows: Logging Driver: json-file Plugins: Volume: local Network: l2bridge l2tunnel nat null overlay transparent Swarm: inactive Default Isolation: process Kernel Version: 10.0 14393 (14393.0.amd64fre.rs1_release.160715-1616) Operating System: Windows Server 2016 Datacenter OSType: windows Architecture: x86_64 CPUs: 1 Total Memory: 1.933 GiB Name: SRV1 ID: VB3B:IGYN:GEFL:6ML7:OQJM:GMCJ:HDNU:Z57W:SWYI:Z2I3:WZKG:O2L4 Docker Root Dir: C:\ProgramData\docker Debug Mode (client): false Debug Mode (server): false Registry: https://index.docker.io/v1/ Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false |
Ok now, the container host is up and running, so we can deploy our first Windows container! For the first example, we will deploy a IIS container, run the following command:
1 2 3 4 5 6 7 8 |
PS > Docker run -d -p 8080:80 --name iis microsoft/iis Unable to find image 'microsoft/iis:latest' locally latest: Pulling from microsoft/iis c480435b7cba: Downloading [==> ] 220.1 MB/4.175 GB 2acd7c473906: Downloading [=============> ] 240.1 MB/922.1 MB a837699b27ea: Download complete e4e8167eafc5: Download complete 0344b06e0e62: Download complete |
Below is the syntax of the Docker command:
1 |
PS > docker run PUBLIC_PORT:PRIVATE_CONTAINER_PORT CONTAINER_NAME IMAGE |
Containers use the PAT concept (Port Address Translation). It means that you must expose container ports through the container host. In my example, Docker will bind the port container number 80 to the port container host number 8080. Then, when I will try to open the IIS website located inside the container, I will use the public port 8080.
The « Name » parameter adds a friendly name to the container. It is not mandatory but it can be useful to manage your containers later.
Finally, you must specify the container image name. Here, I choose the IIS image provided by Microsoft.
When I run the command, Windows checks if the image is available locally (on the container host). If not, then Docker retrieves the image from the Docker hub.
1 2 3 |
PS > Docker run -d -p 8080:80 --name iis microsoft/iis Unable to find image 'microsoft/iis:latest' locally … |
When it’s done, your Windows Container is running. My container host has the following IP Address: 192.168.0.132, so my IIS website is available from 192.168.0.132:8080
IIS Container
To Go Further
Image2Docker
Let’s say you have a server that has been lovingly hand-crafted that you want to containerize? Well, you can use the “Image2Docker” PowerShell module available on GitHub: https://github.com/docker/communitytools-image2docker-win which ports existing Windows application workloads from virtual machines to Docker images. So you can easily convert Windows Services to Windows Containers such as: IIS websites, DNS, DHCP, …
Licensing
Official website contains relatively little information about licensing, but according to the Windows Server 2016 Licensing Datasheet, Standard Edition provides rights for up to 2 Hyper-V containers when all physical cores in the server are licensed and unlimited Windows Server containers for both editions.
Conclusion
Windows containers are already changing the way organizations build systems and deliver services. Containers are increasingly important to ensure that developers and Ops don’t spend too much time to deploy applications.
Container technology is not new in Linux world, but for Microsoft, it’s a revolution. It is important to urgently find the time to understand the ins and outs of implementing containers in your organization.
We have seen, in this article, how to deploy our first Windows container. You will soon notice that Containers are wonderful for Developers and Administrators because containerization allows great flexibility of use and will simplify your deployments. There are still many things to be said about Containers, so in the next articles, I will explain:
- The Docker commands to get started with Docker,
- How to find and download container images,
- How to use Hyper-V Containers,
- How to create your own Container image,
- How to convert Windows services to run in a Windows Container,
- …
I hope that this article has helped you to increase your knowledge about Windows Containers.
Load comments