Docker on Windows
上QQ阅读APP看书,第一时间看更新

Data in layers and the virtual C drive

The virtual filesystem is how Docker can take a set of physical image layers and treat them as one logical container image. Image layers are mounted as read-only parts of the filesystem in a container, so they can't be altered, and that's how they can be safely shared by many containers.

Each container has its own writeable layer on top of all of the read-only layers, so every container can modify its own data without affecting any other containers:

This diagram shows two containers running from the same image. The image (1) is physically composed of many layers: one built from each instruction in the Dockerfile. The two containers (2 and 3) use the same layers from the image when they run, but they each have their own isolated, writeable layers.

Docker presents a single filesystem to the container. The concept of layers and read-only base layers is hidden, and your container just reads and writes data as if it had a full native filesystem, with a single drive. If you create a file when you build a Docker image and then edit the file inside a container, Docker actually creates a copy of the changed file in the container's writeable layer and hides the original read-only file. So the container has an edited copy of the file, but the original file in the image is unchanged.

You can see this by creating some simple images with data in different layers. The Dockerfile for the dockeronwindows/ch02-fs-1:2e image uses Nano Server as the base image, creates a directory, and writes a file into it:

# escape=`
FROM mcr.microsoft.com/windows/nanoserver:1809

RUN md c:\data & `
echo 'from image 1' > c:\data\file1.txt

The Dockerfile for the dockeronwindows/ch02-fs-2:2e image creates an image based on that image, and adds a second file to the data directory:

FROM dockeronwindows/ch02-fs-1:2e
RUN echo 'from image 2' > c:\data\file2.txt
There's nothing special about base images; any image can be used in the FROM instruction for a new image. It can be an official image curated on Docker Hub, a commercial image from a private registry, a local image built from scratch, or an image that is many levels deep in a hierarchy.

I'll build both images and run an interactive container from dockeronwindows/ch02-fs-2:2e, so I can take a look at the files on the C drive. This command starts a container and gives it an explicit name, c1, so I can work with it without using the random container ID:

docker container run -it --name c1 dockeronwindows/ch02-fs-2:2e
Many options in the Docker commands have short and long forms. The long form starts with two dashes, like --interactive. The short form is a single letter and starts with a single dash, like -i. Short tags can be combined, so -it is equivalent to -i -t, which is equivalent to --interactive --tty. Run docker --help to navigate the commands and their options.

Nano Server is a minimal operating system, built for running apps in containers. It is not a full version of Windows, you can't run Nano Server as the OS on a VM or a physical machine, and you can't run all Windows apps in a Nano Server container. The base image is deliberately small, and even PowerShell is not included to keep the surface area down, meaning you need fewer updates and there are fewer potential attack vectors.

You need to brush off your old DOS commands to work with Nano Server containers. dir lists the directory contents inside the container:

C:\>dir C:\data
Volume in drive C has no label.
Volume Serial Number is BC8F-B36C

Directory of C:\data

02/06/2019 11:00 AM <DIR> .
02/06/2019 11:00 AM <DIR> ..
02/06/2019 11:00 AM 17 file1.txt
02/06/2019 11:00 AM 17 file2.txt

Both of the files are there for the container to use in the C:\data directory; the first file is in a layer from the ch02-fs-1:2e image, and the second file is in a layer from the ch02-fs-2:2e image. The dir executable is available from another layer in the base Nano Server image, and the container sees them all in the same way.

I'll append some more text to one of the existing files and create a new file in the c1 container:

C:\>echo ' * ADDITIONAL * ' >> c:\data\file2.txt

C:\>echo 'New!' > c:\data\file3.txt

C:\>dir C:\data
Volume in drive C has no label.
Volume Serial Number is BC8F-B36C

Directory of C:\data

02/06/2019 01:10 PM <DIR> .
02/06/2019 01:10 PM <DIR> ..
02/06/2019 11:00 AM 17 file1.txt
02/06/2019 01:10 PM 38 file2.txt
02/06/2019 01:10 PM 9 file3.txt

From the file listing you can see that file2.txt from the image layer has been modified and there is a new file, file3.txt. Now I'll exit this container and create a new one using the same image:

C:\> exit
PS> docker container run -it --name c2 dockeronwindows/ch02-fs-2:2e

What are you expecting to see in the C:\data directory in this new container? Let's take a look:

C:\>dir C:\data
Volume in drive C has no label.
Volume Serial Number is BC8F-B36C

Directory of C:\data

02/06/2019 11:00 AM <DIR> .
02/06/2019 11:00 AM <DIR> ..
02/06/2019 11:00 AM 17 file1.txt
02/06/2019 11:00 AM 17 file2.txt

You know that image layers are read-only and every container has its own writeable layer, so the results should make sense. The new container, c2, has the original files from the image without the changes from the first container, c1, which are stored in the writeable layer for c1. Each container's filesystem is isolated, so one container doesn't see any changes made by another container.

If you want to share data between containers, or between containers and the host, you can use Docker volumes.