Containers have been available in the Linux world for a number of years. They are a way to virtualize and isolate applications. Windows Server 2016 introduced the technology to the Windows world. Containers are also available on Windows 10 builds post RTM. The container functionality in Windows Server was further enhanced in Windows Server 1709, Windows Server 1803, and Windows Server 2019.
In this chapter, we’ll explain what this exciting new technology is and what you can do with it. This includes how to install the containers feature and the configuration steps you must take before you can use containers. We’ll look at the networking implications of containers and how you can overcome those issues.
Before you can use a container, you need to know how to create one—and manage its life cycle. Containers are an excellent way to deliver applications and, in a DevOps environment, could be a way to simplify your delivery processes. You use container images to move containers and, therefore, application functionality from one machine to another, as we’ll show you toward the end of the chapter.
CHANGES TO CONTAINER TECHNOLOGY ON WINDOWS
Windows Server 2016 Technical Preview 3 (TP3) gave us our first view of containers on the Windows platform. Containers behaved, and were treated, as mini-virtual machines in TP3 through TP5, and you could use Docker or Windows PowerShell to manage your containers.
This suddenly, and surprisingly, changed without warning in Windows Server 2016 RTM, when containers became application isolation objects that matched their implementation on the Linux platform. Docker became the recommended and only practical management technology.
There is a PowerShell module for managing containers— https://github.com/Microsoft/Docker-PowerShell —but the only release (August 2016) is rated as an alpha release, and so it can’t be recommended for use. The module has been deprecated and archived recently, with no further development planned.
Docker is the only practical administration mechanism, unless you want to create your own functionality using Docker.Dotnet— https://github.com/Microsoft/Docker.DotNet .
First, though, just what are these containers that you’ve heard so much about?
Containers Explained
Containers are lightweight virtualized isolation objects for running applications without impacting the rest of your system. The isolation ensures the container has no knowledge of, and no interaction with, other applications or processes that exist on the same host machine.
Note
The Microsoft documentation for containers is available at https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/ . At the time of writing, this documentation isn’t complete and is contradictory in places. Be aware and double-check.
Containers can be easily ported between hosts, as the application in the container has all of the dependencies and configuration data required for its execution.
Container hosts can be physical or virtual machines (VMs). Container portability means that you can create a container for your application on your Windows 10 machine and, when you’re sure its performing as required, port the container to a production host or VM.
Windows Server containers
Hyper-V isolation containers
All Windows Server containers share the kernel of their host’s operating system (OS) but still provide process and namespace isolation. Windows Server containers aren’t a security boundary, so they can’t guarantee to isolate untrusted code. The same kernel version and configuration are required for the host and its Windows Server containers.
Hyper-V isolation containers run in a highly optimized “virtual machine.” You can’t see or interact with this VM; it’s a background object to support only the containers. Each Hyper-V container on a host has its own kernel OS. These containers provide the same security assurances as a VM. Different kernel versions and configurations can be run on the host, for example a Windows 10 container host uses Hyper-V isolation to run containers, based on the Windows Server kernel.
Windows Server and Hyper-V Container Comparison
Windows Server Containers | Hyper-V Containers |
---|---|
Share Windows kernel | Own Windows kernel |
Memory shared through host | Memory assigned directly |
OS trusts applications | Applications not trusted by OS |
Applications trust each other | Applications don’t trust each other |
Faster startup | Slightly slower startup |
LESS ISOLATION | MORE ISOLATION |
The important point to note is that Hyper-V containers provide more isolation at the OS and application level than Windows Server containers.
Before moving on to installing the containers feature, we must spend a moment discussing container management.
Managing Containers
In the Linux world, the de facto standard for managing containers is Docker— www.docker.com/ . Containers are often referred to as Docker containers when, in fact, Docker is a management API for containers. Docker itself refers to Docker as a container platform ( www.docker.com/what-docker ).
Irrespective of its actual definition, Docker is what you will require in order to manage containers in a Windows platform. The documentation for the Docker command-line interface (CLI) is available online at https://docs.docker.com/engine/reference/commandline/docker/ .
Note
There isn’t a GUI option, from Microsoft or Docker, for managing containers in a Windows environment. You have to use the command line. Kitematic is an open source version of a legacy GUI for Windows (and Mac), if you want to try a GUI option. Most Docker-related documentation assumes management via the command line.
The advantage of using Docker is that it is a standard, and there are many books and articles written on the subject. Unfortunately, most of those are written for Linux users and will require some work to “translate” into Windows. You can use Docker from a Linux machine to administer containers on a Windows machine and vice versa.
The disadvantage to using Docker is that it has an arcane syntax typical of traditional Linux or Windows command-line utilities. If you’ve become accustomed to the (usually) consistent and logical syntax of PowerShell, you’ll have to modify your expectations, unfortunately. The Docker-PowerShell module we mentioned earlier could become an alternative, but it’ll need a lot of work. Alternatively, you could create a number of functions to wrap Docker functionality that would provide, at least, a basic level of PowerShell functionality. We’ll show you some examples of such functions later in the chapter.
So, how do you get containers up and running?
Installing the Containers Feature
Windows Server
Windows Server Insider Previews
Windows 10
Note
At the time of writing, Windows Server is taken to include Windows Server 2016, Windows Server 1709, and Windows Server 1803. Windows Server Insider Previews is taken to mean the Windows Server 2019 Previews and all future preview releases. Once Windows Server 2019, or future SAC versions, have been officially released, we expect the container feature installation instructions for Windows Server will apply to them as well.
The one option we won’t cover is installation of containers on a Nano server machine. Nano server was introduced with Windows Server 2016 as an ultra-low footprint installation option that could perform a number of infrastructure roles, including being a container host. As of Windows Server 1709, Nano server has been relegated to being a container OS only. All of the infrastructure roles have been removed, and you can only use Nano server as the basis of a container. We don’t recommend using Nano server as a container host, owing to the change in emphasis from Microsoft. The Nano server documentation is available online at https://docs.microsoft.com/en-us/windows-server/get-started/getting-started-with-nano-server , but the container-related documentation has been removed.
Warning
Microsoft is expending a lot of development effort on container-based technology. The installation details have changed a number of times over the last few years. Before starting an installation on a new machine, double-check the documentation, to ensure that things haven’t changed. Prime candidates for change include the provider modules and Docker installation package names.
Let’s start by discovering how to install the containers feature on Windows Server.
Installing Containers Feature on Windows Server
Install the Docker provider.
Download and install Docker.
Download container images.
Create containers.
You’ll learn about the first two parts of the procedure in this section. Finding, downloading, and using container images will be addressed in later sections.
Note
We’re going to use the Server Core option for all of our Windows Server container hosts. Containers don’t have an administration GUI, and we want to keep the overhead of using containers as low as possible, making Server Core the ideal option. Windows Server 1709 and Windows Server 1803 are only available as Server Core, which is also a powerful driver for using this option.
The version numbers may be different. Even the names may be different, given the rate of change Microsoft is imposing, which is why we urge you to check the documentation.
FIRST-TIME GALLERY USER
Answer with Y and press Enter, for the install to proceed.
You’ll then get your results. Future access to the gallery won’t show the message about the NuGet provider, as it’s already installed.
DockerMsftProvider: Use for production versions of Windows Server—Windows Server 2016, Windows Server 1709, Windows Server 1803, etc.
DockerProvider: Use for Windows Server Insider Previews.
DockerMsftProviderInsider: Ignore. This was the provider to use for Windows Server Insider Previews but has been superseded by DockerProvider. We expect that this provider will be removed eventually.
You must accept the message to install from an untrusted source and press Enter to continue or use the -Force parameter to bypass the message.
Note
If you hit any problems in the download and install of the Docker package, follow the instructions in the “Troubleshooting the Installation Process” section.
The containers feature and Docker are now installed on your server. Let’s turn to the Windows Server previews for a moment.
Installing Containers Feature on Windows Server Insider Previews
Installing the containers feature on a Windows Server Preview instance is very similar to the installation on Windows Server, except you use the preview provider.
You should be able to install containers on any of the Windows Server versions now. The last installation option to consider is Windows 10.
Installing Containers Feature on Windows 10
The installation procedure on Windows 10 is completely different—isn’t consistency a jewel. You’ll need to have the Hyper-V feature installed and working on your Windows 10 system before installing Docker.
First, you must download the Docker for Windows installer from https://download.docker.com/win/stable/InstallDocker.msi . Installation instructions are available from Docker at https://docs.docker.com/docker-for-windows/install/ , but they aren’t totally consistent with those in the Microsoft documentation at https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-10 .
Our install experience can only be described as awful. Once you’ve started it, you’ll get no feedback—not even when it finishes! You’ll have to add your user account into the Docker-users local group. (The installation creates the group but doesn’t add you to it!) If you’re not in the group, Docker for Windows won’t start. Once you’ve added yourself to the group, either log off and log on or restart the machine. We recommend restarting.
The Docker installation procedure will create a VM switch called DockerNAT with a switch type of Internal.
You’ll have to start Docker for Windows manually, the first time you use it. Docker should start automatically on subsequent machine restarts.
Sometimes things go wrong and you may have to become more involved in the installation process .
Troubleshooting the Installation Process
You could try to use Save-Package, but we got a similar error. This seems to a be a common issue discussed in the following thread: https://github.com/OneGet/MicrosoftDockerProvider/issues/15 .
Restart the VM to finish the installation and start the Docker service.
You’ve spent a lot of time covering the installation options, but given the differences in procedure between the various options, it’s important that you get the installation correct. Now that installation is out of the way, it’s time to create your first container.
Your First Container
Find a container image.
Download a container image.
Create the container.
First things first. How do you find a container image?
Finding Container Images
Supported Host and Container Operating System versions—Windows Server Host
Container Operating System | Host Operating System | |||
---|---|---|---|---|
Windows Server 2016 | Windows Server 1709 | Windows Server 1803 | Windows Server 2019 | |
Windows Server 2016 | Supported Windows Server or Hyper-V isolation | Supported Hyper-V isolation only | Supported Hyper-V isolation only | Supported Hyper-V isolation only |
Windows Server 1709 | Not supported | Supported. Windows Server or Hyper-V isolation | Not supported | Not supported |
Windows Server 1803 | Not supported | Not supported | Supported Windows Server or Hyper-V isolation | Supported Hyper-V isolation only |
Windows Server 2019 | Not supported | Not supported | Not supported | Supported Windows Server or Hyper-V isolation |
Supported Host and Container OS Versions—Windows 10 Host
Container Operating System | Host Operating System | ||
---|---|---|---|
Windows 10 1609 or 1703 | Windows 10 1709 | Windows 10 1803 | |
Windows Server 2016 | Supported Hyper-V isolation only | Supported Hyper-V isolation only | Supported Hyper-V isolation only |
Windows Server 1709 | Not supported | Supported Hyper-V isolation only | Supported Hyper-V isolation only |
Windows Server 1803 | Not supported | Not supported | Supported Hyper-V isolation only |
Windows Server 2019 | Not supported | Not supported | Not supported |
New versions of Windows 10 and Windows Server are released approximately every six months. This will add an additional column to the tables.
SAC releases have an 18-month life cycle. As older versions are withdrawn, columns will be removed from the tables.
Windows Server can run a container as a Windows container if, and only if, the container OS image version matches the host version. As an example, Windows Server 1803 can only run container images with a Windows Server 1803 OS as Windows containers.
Windows server can run earlier versions of a container OS image as Hyper-V containers. Windows Server 1803 can run Windows Server 1709 and Windows Server 2016 container images as Hyper-V containers, for example.
A Windows Server host can’t run a container using an OS image from a later version container OS image, for example, Windows Server 1709 can’t run a Windows 1803 container image.
Windows 10 can only run Hyper-V containers that match or predate the Windows 10 version number. For example, Windows 10 1709 can run Windows Server 2016 and Windows Server 1709 containers but not Windows Server 1803.
Type Container Available, Based on Host Operating System
Host Operating System | Windows Server Container | Hyper-V Container |
---|---|---|
Windows Server 2016 (Standard or Datacenter) | Server Core or Nano server | Server Core or Nano server |
Windows Server 1709 (Standard or Datacenter) | Server Core or Nano server | Server Core or Nano server |
Windows Server 1709 (Standard or Datacenter) | Server Core or Nano server | Server Core or Nano server |
Windows Server 2019 (Standard or Datacenter) | Server Core or Nano server | Server Core or Nano server |
Nano server (Windows 2016 ONLY) | Nano server | Server Core or Nano server |
Windows 10 Pro or Enterprise | Not available | Server Core or Nano server |
Note
We expect that these rules will continue to work beyond Windows Server 2019.
With the background information out of the way, you’ll need to know where to look to find your container OS images.
The answer is the Docker Hub. Microsoft has embraced the Docker ecosystem and made their container images available through Docker’s portal: https://hub.docker.com/ . The Docker Hub directs you to the Docker Store as the new place to find container images, but at the time of writing, the Docker Hub was still the primary point for finding container images.
Note
You’ll need to create an account on the Docker Hub to get the most from it.
The commands will pull a Windows Server 2016, Windows Server 1709, and Windows Server 1803 image respectively. The repository is Microsoft/windowsservercore and the optional tags are 1709 and 1803. You can view the available options for a container image in the Docker Hub. Navigate to the appropriate repository and click Tags.
You’re pulling the previews from a different repository.
Note
The Insider images should be used only for development and testing. They are part of the Insider program and, therefore, subject to change.
Servicing stack
.NET core
PowerShell and WMI
Administrator accounts
Indicative Sizes of Container Operating System Images
Operating System | Nano Server Container Image | Server Core Container Image |
---|---|---|
Windows Server 2019 | 236MB | 3.42GB |
Windows Server 1803 | 337MB | 4.76GB |
Windows Server 1709 | 329MB | 5.58GB |
Windows 2016 | 1.1GB | 10.4GB |
As you can see from Table 17-5, Microsoft is working to decrease the size of the base OS container image with each release.
ABOVE AND BEYOND
Microsoft has stated that a new type of container image will be introduced with Windows Server 2019: https://blogs.technet.microsoft.com/virtualization/2018/06/27/insider-preview-windows-container-image/ .
The new image option will contain API dependencies that aren’t in the Server Core or Nano server images. This means the option will have more functionality, including proofing support and graphics support, but will be bigger.
We’ll be using the Server Core and Nano server images in the rest of the book.
The number of images you ask for must be in the range 1–100. Some of the images returned will be from Microsoft, and others from individuals.
Note
Trust is an issue when using images from the Docker Hub, as with any online repository. Any container image you use from the Docker Hub should be rigorously tested in your environment before use.
In reality, the search option in the Docker command-line utility doesn’t appear to have evolved to match the growth of the Docker ecosystem. In reality, it’s not useful for any practical searches, and you’re better off using the browser.
Now that you know how to find your container images, it’s time to download them.
Downloading Container Images
Note
The preceding 1803 tagged images will be used in the rest of the book. If you’re using Windows Server 2016 or Windows Server 1709, substitute the appropriate image names.
The IIS specifics will be merged with the base image, to produce the final image.
When downloading, if you get an error such as Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io: no such host or an indication of a time-out, then try stopping and restarting the Docker service. Attempt the download again in a new instance of PowerShell or cmd.
You’ve found your images and downloaded them. It’s time to create a container.
Creating a Container
In both cases, you’re starting a container, based on the stated image, and telling the container to run cmd.exe and echo Hello World! The output is automatically returned to your console, and the container stops. These containers are running as Windows Server containers.
Note
On Windows Server 2019 Insider Preview, we had to install Hyper-V, after enabling nested virtualization on the VM, to enable containers to run.
You’ll be using the docker run command extensively. It’s worth reading the full documentation at https://docs.docker.com/engine/reference/commandline/run/ .
The display is wrapped, unfortunately, but you should be able to follow it. Docker will automatically assign the container ID and the name. The container ID is the shortened version, as you’ll see later. The name is random!
Later in the chapter, you’ll be running containers that don’t automatically exit. You’ll learn then how to stop and restart them.
The containers you’ve run so far have all been Windows containers. It’s time to investigate Hyper-V containers.
Running Hyper-V Containers
They ensure application and OS isolation.
They can run a container image version that predates the host OS version.
The host is Windows 10.
You might think that using Windows 10 as a host isn’t a good idea, but in reality, you can develop and test the container on your workstation and then move the container to a production host, where it could run as a Windows or Hyper-V container, depending on the scenario.
This starts a continuous ping process. The -d (-detach) parameter runs the container in the background and prints the container ID to the screen. Note that you get the long version of the container id.
There’ll be one instance of VMWP per running VM on your Hyper-V host. Starting a container in Hyper-V isolation mode will also spawn a new instance of the VMWP.
You’ve learned how to create containers, but you’ve only connected to them from the host. You must learn how to attach a container to your network, so that the application can be accessed from any client.
Container Networking
Docker makes changes to your networking configuration when you install it on a Windows machine (physical or VM) that’ll become a container host. We’ll start by explaining those changes, what they mean, and how to use and then examine the options you have for networking containers.
Default Container Network
Network Prefix, Subnet Mask, and Number of Containers per Network
Prefix | Subnet Mask | IP Addresses | Containers |
---|---|---|---|
20 | 255.255.240.0 | 4096 | 4094 |
21 | 255.255.248.0 | 2048 | 2046 |
22 | 255.255.252.0 | 1024 | 1022 |
23 | 255.255.254.0 | 512 | 510 |
24 | 255.255.255.0 | 256 | 254 |
The address 172.22.80.1 is part of the 172.16.0.0/12 private address space (see https://technet.microsoft.com/en-us/library/cc958825.aspx ).
Get-ContainerNetwork is in the Containers module, which has four cmdlets for working with container networks.
Before we go any further, we’d better explain the term NAT, which is used in the name of the adapter and as the network type or mode. NAT stands for “Network Address Translation.” It’s a technique in networking wherein an internal address, in this case, in the 172.22.80.0/20 range, is mapped to an address and port on the machine’s network adapter, so that the container can communicate with machines external to the host. We’ll explain this further with an example.
You’ll recognize that the IP address of the default gateway is the same as the network adapter Docker automatically installs.
The computer name is set to the container ID. Note that the computer type is set to Container.
You’ll notice that we haven’t given any credentials when creating the PowerShell remoting session. Don’t let that fool you into thinking that the container is part of your AD. It isn’t. Containers don’t create AD objects and aren’t part of your AD.
There is also a loop back adapter: 127.0.0.1.
If your container host has a GUI and, therefore, a browser, you’ll be able to connect to http:// 172.21.142.23/ and view the default web site. You won’t be able to ping the container or connect to the web site from another host, as the 172.21.142.23 address is only visible on the container host. You must create a mapping from the 172.21.142.23 address to the external IP address of the host, to make the web site visible on the external network.
Creating an NAT Mapping
In this case, you’re mapping port 80 (HTTP) and port 443 (HTTPS) to the corresponding port number on the external NIC. The order in which you define the ports is important. It should be -p <external port>:<container port>.
The instance of the browser on the left accesses the web site, using the server name http://W1803CN01, and that on the right uses the IP address http://10.10.54.60, which is the IP address of the container host.
The Policies parameter shows the port mappings between the container and the external NIC.
The display is wrapped, because of the width of the page, but you can see the PORTS information at the beginning of the last line.
In this case, you’re mapping port 80 on the container to port 8080 on the external NIC. You can connect to the web site in the container, from an external machine, by using http://W1803CN01:8080/ or http://10.10.54.60:8080/. You can use the same techniques as earlier to view the port mappings.
Using NAT works for a small number of containers—ideal for a development environment. NAT breaks down when you have to run many containers on a host, especially if you have to remember the port mappings to connect to the container from an external machine.
Other Network Options
By default, containers use the NAT network that’s created when you install the containers feature. Other network options are available, as shown in Table 17-7.
Container Networking Options
Network Type | Description |
---|---|
Network AddressTranslation (NAT) (default) | Containers receive an IP address from the range defined when the NAT network is created. Multiple NAT networks per host are support in Windows 1709 and later versions. Port mapping is supported. |
Transparent | Containers are directly connected to the physical network. IP addresses are assigned statically or via DHCP. |
Overlay | For use with Docker Swarm. Containers can communicate with other containers on the same network, across multiple hosts. |
L2Bridge | Container is on same IP subnet as host. Container IP addresses are assigned statically. All container end points have the same Mac address (layer-2 address translation [Mac rewrite occurs]). |
L2Tunnel | This is for the Microsoft cloud stack only. |
Transparent Networks
As an example of another network option, we’ll show how to create a transparent network for your containers.
This command creates a transparent container network attached to the network adapter, named LAN. The subnet and default gateway are set. This is required if you’re going to set IP addresses transparently. The final argument is the network name.
Your container is now on the external network with a pingable IP address. You’ll be able to connect to your container from an external host using http://10.10.54.200. If you create a static DNS entry, you could connect using that name too.
Working with Containers
Create container.
Run container—possibly stop and start a container.
Remove container.
This doesn’t cover all the options, though. You also must be able to modify your container images. You saw how to use PowerShell remoting to connect to a container, earlier in the chapter.
Let’s start by looking a bit more at how to create and connect to your container.
Creating Containers
This will create the container, run the command, return the results, and shut down the container.
You can view the full syntax and options at https://docs.docker.com/engine/reference/commandline/run/ .
You’ll usually run in the background, but you can run containers interactively.
Interactive Containers
If you run a container interactively (by using the -it option), you are immediately connected to the container, as shown in Figure 17-5.
A new PowerShell session is generated within the container, and your current session is connected to it. You’ll see the PowerShell start banner and a new (and different) prompt, as in Figure 17-5. The console overwriting itself seems to be a console artifact.
If you repeat the exercise of retrieving the PowerShell PID, you’ll get a different result—1960, in this case. You can run PowerShell commands, and they execute within the container. Getting the PowerShell process only shows the process within the container—isolated environment—though there are four instances of PowerShell running on the host at that time, including the one in the container.
You can use the exit command to close the container instance of PowerShell, which will also shut down the container. Check the PID, and you’ll see that you’re back in your original PowerShell session.
TRY IT YOURSELF
Experiment with running containers interactively. What would stop you from accessing a container interactively?
This approach works when you want to work interactively with a container, but what about a situation in which you have multiple containers on a host? You must be able to pick and choose which containers to work with, meaning you must be able to identify your containers.
Container Identification
Short (truncated) ID
Full ID
Name
The short ID is the first 12 characters of the full ID.
It’s worth assigning names to your containers, even though some Docker commands expect to work with IDs (usually the short ID), rather than container names. Container names must be unique.
TRY IT YOURSELF
Identify the containers on your machine. Which containers are stopped and which are running?
The commands you’ve seen so far have been to create and immediately run a container. You have the option of creating the container and running it as two separate actions.
Pre-creating Containers
In this example, you’re creating another instance of the IIS container but not starting it. The docker ps command uses the table option to display a header for each column. The columns are spaces using tabs ( ). Note that the long ID is supplied when the container is created, but the short ID is usually used in subsequent commands.
TRY IT YOURSELF
Pre-create a container and then start it.
You now have three instances of your container running. The next step is to stop the containers or remove them from the host.
Stopping and Removing Containers
This is the type of scenario in which PowerShell, with its ability to filter and pipe objects, would be of real benefit. Use the Docker commands you need, to quietly get the running containers to use as the input to docker stop.
Once you’ve stopped the containers, you can remove them.
Note
Attempting to remove a running container will generate an error.
You need the -a parameter on docker ps, to view non-running containers.
TRY IT YOURSELF
Stop the running containers on your system. Remove all existing containers on your system.
You’ve installed the container feature, downloaded container images, and created containers from those images. At some stage, you’ll have to modify a container image and roll that changed image into production.
Modifying and Using Container Images
Containers are very lightweight objects and, therefore, easy to move around your environment. They are a great component to include in your DevOps procedures. In earlier sessions, you’ve seen containers running IIS. Modifying the web site is a common occurrence in application development.
Create an IIS container on a development machine.
Modify the web site.
Create a container image from the modified container.
Move the new image to our production system.
Create a container in production from the new image.
The first step is to create the container.
Create Development Container
Ensure that you can connect to the web site.
Note
In reality, at this stage, you’d complete a test sequence on your web site or application.
Now that you have a working container, it’s time to modify the web site.
Modify Web Site
The change in file survives stopping and starting the container. After the web site changes have been tested, it’s time to move the change into production.
Create Container Image
Changes to containers are propagated through the organization by the use of container images. You’ve already seen a number of container images in use that you downloaded from the Docker Hub. In this section, you’ll create an image from the IISdev container you used in the previous section.
Note
Windows doesn’t support the commit of a running container. If you try, you’ll get an error message!
Note
Windowsservercore is abbreviated to win..ore, to make the text fit the page.
You can then copy the image to one or more production hosts. One of the easiest ways to perform the copy is to use a PowerShell remoting session, as you’ve seen earlier.
Once your container image has been copied, you can use it to create new containers.
Using the New Container Image
The ability to modify running containers and create an image from that container that can be exported to other machines gives you a very fast, safe way to deploy applications in your environment. If your organization is embracing the DevOps principles, you’ll find that containers can play a significant role in your application deployment strategies.
TRY IT YOURSELF
Follow the steps in this section to modify a container, create a new image, copy the image to a new machine, and create a container from the new image.
The steps involved in modifying a container and creating an image that can be used throughout the organization are manually intensive. The container images can be several gigabytes in size, leading to slow copy times. It would be useful if there were a way to automate the production of new images and reduce the size of data that had to be copied around the environment.
Automating Image Creation
Effectively storing images as code
Easily and accurately creating and re-creating container images
Enabling continuous integration between container images and the development cycle
A Docker file is a text file that contains the instructions to create a new container image—using an existing base image—the commands to be run when the image is created, and the commands to be run when containers are created from the image. The Microsoft documentation for Docker files is located at https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-docker/manage-windows-dockerfile .
As an example, let’s rework the modification of the web site that was performed manually in the previous section.
In this version, we’ve added the fact that we’re using a Docker file to make the differences obvious. The next task is to create a Docker file. Visual Studio Code (the recommended editor for PowerShell v6 and later versions— https://code.visualstudio.com/ ) works with PowerShell and many other languages, including Docker files.
The FROM directive instructs Docker to use the microsoft/iis:windowsservercore-1803 image as the basis of the build. The COPY command instructs the build process to copy the new version of iisstart.png into the image.
Many other tasks can be accomplished using Docker files. The Docker file reference can be found at https://docs.docker.com/engine/reference/builder/#usage .
In this case, you’re using a Docker file IIS2.dockerfile to build a new image called prohyperv/iis:version2. The dot at the end of the command line instructs Docker that all of the required files are in the current directory. It’s recommended that you keep the Docker file and other required files together, for simplicity.
Once you’ve tested the new web site, you can copy the Docker file and any other required files to your production machine(s). This is much less data than a full image, so it is much quicker. Re-create the image, using the same docker build command. You can then create containers from the new image.
Using Docker files is a quicker and easier way to modify your container images and get the new image into production.
TRY IT YOURSELF
Follow the steps in this section to create a new image using a Docker file. Create a container from the new image. Copy the Docker file and data to another system and re-create the image and container.
The containers you’ve been working with throughout the book use the Windows OS. You can also run containers based on Linux.
Linux Containers on Windows
The Windows 10 Fall Creators Update and Windows Server 1709 introduced the capability of running Linux containers on Windows (see https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/linux-containers ).
The posts in various online forums indicate that this is still an experimental technology. People are experiencing varying degrees of success. You should also note that the documentation is very poor at the time of writing. The tutorials are contradictory, and a number of them have broken links.
Run Windows 10 Fall Creators Update or Windows Server 1709, as a minimum. We used Windows 10 1803. We recommend that you use the latest version possible of the Windows OS, as Linux containers on Windows are still an experimental feature.
Use the latest version of Docker—18.03 or later versions.
Enable experimental features. Open Docker Settings ➤ Daemon and check the Experimental features box.
Switch Docker to running Linux containers (see installation section earlier in this chapter) or use PS> & $env:ProgramFilesDockerDockerdockercli.exe -SwitchDaemon.
Have Hyper-V installed. You’ll be running the containers in Hyper-V isolation mode. If you check Hyper-V Manager, you’ll find that a VM called MobyLinuxVM is running. It’s used to support the containers.
You’re running the latest version of PowerShell 6.0 in a Linux container on Windows 10!
Note
If you start a Linux container, then switch back to Windows containers, your Linux container will continue to run but you won’t be able to manage it until you switch back to Linux containers. The same is true for running Windows containers, if you switch to Linux containers. You can run Linux and Windows containers side by side, but you can only manage one or the other at a time, if you use the switching mechanism. See later in the section for an alternative approach.
Once the container is shut down, you’ll lose these changes, so remember to create an image from the container, so that you can still access the tools you’ve downloaded.
If you want to experiment with the latest PowerShell preview versions, or with other Linux distributions, you’ll find them available as containers at https://hub.docker.com/r/microsoft/powershell/ .
You’ll also have to use the platform parameter when pulling the container image from Docker Hub.
To run containers in this manner, you’ll have to use Docker 18.03-ce-win59 as a minimum version and have the experimental features enabled.
TRY IT YOURSELF
Experiment with Linux containers on your Windows system. Can you find other Linux-based containers that will run on Windows?
Our recommendation, for now, is to experiment, if this is a feature you require, but be very aware that it’s a rapidly changing technology. Keep a close watch on future Windows and Docker releases, for further advances and enhancements.
Recommendations
Use containers, where appropriate. They’re not suitable for all scenarios but do provide a valuable option for virtualizing applications.
Pick a version of Windows Server and stick with it, but be aware that the SAC releases only have an 18-month life cycle. If you do decide to upgrade, remember that your existing containers can be run on newer versions of the OS, using Hyper-V isolation. You can upgrade the hosts and containers as a two-step process.
We recommend Windows Server 1803, as a minimum, for your container host, because it has the latest enhancements to run containers on Windows.
Use Docker files for building images. They are much smaller and quicker to move between machines than full images.
Learn Docker syntax. PowerShell is the automation tool of choice, but there isn’t a module for managing containers. Wrapping Docker commands in PowerShell functions could be a viable alternative, if you’re going to be heavily invested in using containers.
Before the chapter closes, we’d like to offer you a few ideas for some next steps in learning about containers.
Next Steps
We haven’t space in this book to cover all aspects of containers. It’s a rapidly changing field, and you’ll have to keep checking the links in this chapter for changes. As next steps, we recommend that you investigate which applications in your organization would benefit from using containers. Remember that big-bang projects generally fail, so plan a gradual introduction.
In this chapter, we’ve shown you how to perform manual actions to manage your container environment. When you get to the point of having a large number of containers, you should start to think about orchestration.
An orchestrator is used to perform a number of tasks, including scheduling, health monitoring, failover, scaling, networking, and application upgrades. There are two orchestrators you should investigate first.
The first is Docker Swarm, which provides orchestration capabilities, native clustering of Docker hosts, and scheduling of container workloads. An introduction is available at https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/swarm-mode . It has the advantage of being from Docker and has been the leading orchestrator.
Kubernetes can be used with Windows Server 1709 and later versions. Kubernetes is used to manage containerized workloads and services, including declarative configuration, load balancing, and automation. Kubernetes has taken over from Docker Swarm as the de facto orchestrator https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/getting-started-kubernetes-windows and https://kubernetes.io/docs/home/?path=users&persona=app-developer&level=foundational .
One drawback to both orchestrators is that they use a Linux system as the control server.
Lab Work
This has been a very long chapter. Rather than supply specific exercises, we recommend that you complete all of the Try It Yourself sections. The preceding “Next Steps” section provides some ideas for further investigation of containers.