- Docker on Windows
- Elton Stoneman
- 827字
- 2021-07-02 19:53:21
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 writable layer on top of all 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 writable layer and hides the original read-only file. So the container has edited a 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 image dockeronwindows/ch02-fs-1 uses Nano Server as the base image, creates a directory, and writes a file into it:
# escape=`
FROM microsoft/nanoserver
RUN md c:\data `
echo 'from layer 1' > c:\data\file1.txt
The Dockerfile for the image dockeronwindows/ch02-fs-2 creates an image based from that image, and adds a second file to the data directory:
# escape=`
FROM dockeronwindows/ch02-fs-1
RUN echo 'from image 2' > c:\data\file2.txt
I'll build both images and run an interactive container from dockeronwindows/ch02-fs-2, 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 powershell
The ls command is a PowerShell alias for Get-ChildItem, which I can use to list the directory contents inside the container:
> ls C:\data
Directory: C:\data
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 6/22/2017 7:35 AM 17 file1.txt
-a---- 6/22/2017 7:35 AM 17 file2.txt
Both 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 image, and the second file is in a layer from the ch02-fs-2 image. The PowerShell 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:
PS C:\> echo ' * ADDITIONAL * ' >> c:\data\file2.txt
PS C:\> echo 'New!' > c:\data\file3.txt
PS C:\> ls c:\data
Directory: C:\data
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 6/22/2017 7:35 AM 17 file1.txt
-a---- 6/22/2017 7:47 AM 53 file2.txt
-a---- 6/22/2017 7:47 AM 14 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:
PS C:\> exit
PS> docker container run -it --name c2 dockeronwindows/ch02-fs-2 powershell
What are you expecting to see in the C:\data directory in this new container? Let's take a look:
> ls C:\data
Directory: C:\data
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 6/22/2017 7:35 AM 17 file1.txt
-a---- 6/22/2017 7:35 AM 17 file2.txt
You know that image layers are read-only and every container has its own writeable layer, so the results should be clear. 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.