In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly explains "what is the working principle of AUFS". Interested friends may wish to take a look at it. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "how AUFS works".
Rootfs
Rootfs (root file system) is a file system mounted on the root of the container to provide an isolated execution environment for the container process, which is called "container image". So, one of the most common rootfs, or container images, will include directories and files like / bin,/etc,/proc, and so on:
$ls / bin dev etc home lib lib64 mnt opt proc root run sbin sys tmp usr var
The / bin/bash you execute after you enter the container is the executable file in the / bin directory, which is completely different from the / bin/bash of the host. For the Docker project, its core principle is actually for the user process to be created:
Enable Linux Namespace configuration
Sets the specified Cgroups parameter
Switch the root directory of the process (Change Root).
In addition, it needs to be clear that rootfs is just a file, configuration, and directory contained by the operating system, not the operating system kernel. In the Linux operating system, these two parts are stored separately, and the operating system loads a specified version of the kernel image only when it is booted. Therefore, rootfs only includes the "body" of the operating system, not the "soul" of the operating system.
So, for containers, where is the "soul" of this operating system? In fact, all containers on the same machine share the kernel of the host operating system. This means that if your application needs to configure kernel parameters, load additional kernel modules, and interact directly with the kernel, you need to be aware that these operations and dependent objects are the kernel of the host operating system. It is a "global variable" for all containers on the machine. This is also one of the main drawbacks of containers compared with virtual machines: after all, the latter not only has simulated hardware machines acting as sandboxie, but also runs a complete Guest OS for applications to toss around in each sandboxie.
Federated file system
Docker introduces the concept of layer in the design of mirrors. In other words, each step of the user creating an image generates a layer, that is, an incremental rootfs.
Of course, the idea is not made up out of thin air, but uses a capability called federated file system (Union File System).
Union File System, also known as UnionFS, the main function is to jointly mount multiple directories in different locations (union mount) to the same directory. For example, I now have two directories An and B, each with two files:
$tree. ├── A │ ├── a │ └── x └── B ├── b └── x
Then, using joint mount, I mount these two directories to a common directory C:
$mkdir C $mount-t aufs-o dirs=./A:./B none. / C
At this point, when I look at the contents of directory C, I can see that the files under directories An and B have been merged together:
$tree. / C ├── a ├── b └── x
As you can see, in this merged directory C, there are three files a, b, x, and there is only one x file. This is the meaning of "merger". In addition, if you make changes to a, b, x files in directory C, these changes will also take effect in the corresponding directories An and B.
There are three most commonly used federated file systems in Docker: AUFS, Devicemapper, and OverlayFS.
AuFS
AUFS is not currently incorporated into the Linux kernel mainline, so only a few operating systems such as Ubuntu and Debian support AUFS. You can use the following command to see if your system supports AUFS:
Root@cr7-ubuntu:~# grep aufs / proc/filesystemsnodev aufs
After executing the above command, if the output contains aufs, it means that the current operating system supports AUFS. AUFS is recommended for use in Ubuntu or Debian operating systems. If you want to use AUFS in operating systems such as CentOS, you need to install the AUFS module separately.
After confirming that the operating system supports AUFS, you can configure the startup parameters of Docker. First create a new daemon.json file under / etc/docker and write the following:
{"storage-driver": "aufs"}
Then restart Docker using the following command:
Systemctl daemon-reload & & systemctl restart docker
After Docker restart, you can use the docker info command to check whether the configuration takes effect:
Root@cr7-ubuntu:~# docker infoClient: Debug Mode: falseServer: Containers: 1 Running: 1 Paused: 0 Stopped: 0 Images: 1 Server Version: 19.03.8 Storage Driver: aufs # you can see that Storage Driver has become aufs Root Dir: / var/lib/docker/aufs Backing Filesystem: extfs Dirs: 3 Dirperm1 Supported: true Logging Driver: json-file Cgroup Driver: cgroupfs.
You can see that Storage Driver has become aufs, proving that the configuration has taken effect, and after the configuration has taken effect, you can use AUFS to provide a federated file system for Docker.
How AUFS works
AUFS is a federated file system, which means it uses multi-tier directory storage on the host. Each directory is called branch in AUFS and layer in Docker, but the final presentation to the user is an ordinary single-tier file system. The process in which multiple layers are presented in a single-tier manner is called federated mount.
As shown in the figure above, each image layer and container layer is a subdirectory under / var/lib/docker, the image layer and container layer are under the aufs/diff directory, the directory name of each layer is the ID value of the image or container, the joint mount point is under the aufs/mnt directory, and the mnt directory is the real container working directory.
The following is a detailed description of the changes in the directory structure under the aufs folder before and after the creation of the container: 1. When an image does not generate a container, the storage structure of AUFS is as follows.
Diff folder: stores mirrored content, and each layer is stored in a subfolder named after the mirror layer ID.
Layers folder: stores metadata for mirror layer relationships, where each mirror layer under the diif folder has a file containing the ID of all parent mirrors of that layer mirror.
Mnt folder: the joint mount point directory, which is empty when no container is generated.
two。 When an image has been generated into a container, the AUFS storage structure changes as follows.
Diff folder: when the container is running, the container layer is generated in the diff directory. The container layer is readable and writable, and stores different files (add or delete) of the container relative to the mirror layer. In addition, there are layers in the diff directory that end with "- init", sandwiched between the container layer and the mirror layer. The Init layer is an internal layer generated separately by the Docker project, which is specially used to store / etc/hosts, / etc/resolv.conf, and so on.
Layers folder: add metadata related to the container layer.
Mnt folder: the joint mount point of the container, which is consistent with the contents of the files seen in the container.
AUFS work scenario
Read a file
When the file exists in the container layer: when the file exists in the container layer, it is read directly from the container layer.
When the file does not exist in the container layer: when the container is running, you need to read a file, if it does not exist in the container layer, look for the file from the mirror layer, and then read the contents of the file.
The file exists in both the mirror layer and the container layer: when the file we read exists in both the mirror layer and the container layer, it will be read from the container layer.
Modify a file or directory AUFS modifies the file using the working mechanism of copying when writing, which can save storage space to the maximum extent. The specific file operation mechanism is as follows.
Modify the file for the first time: when we modify a file in the container for the first time, AUFS will trigger the copy operation on write. AUFS first copies the file from the mirror layer to the container layer, and then performs the corresponding modification operation.
The operation of copying when AUFS writes will copy the entire file, and if the file is too large, it will greatly reduce the performance of the file system, so when we have a large number of files to be modified, AUFS may have significant delays. Fortunately, the copy-on-write operation is triggered only when the file is modified for the first time and does not have much impact on daily use.
Delete a file or directory: when a file or directory is deleted, AUFS does not actually delete it from the image, because the mirror layer is read-only and AUFS creates a special file or folder (a file or folder starting with .wh under the diff directory) that blocks access to the container.
Before AUFS demonstrates the AUFS of Docker to pull the image
The diff,layers,mnt directory is empty before pulling the image.
Root@cr7-ubuntu:/var/lib/docker/aufs# tree-L 2. ├── diff ├── layers └── mnt3 directories, 0 files after pulling the image
Pull a basic image of apline:latest
Root@cr7-ubuntu:/var/lib/docker/aufs# docker pull alpineUsing default tag: latestlatest: Pulling from library/alpine188c0c94c7c5: Pull completeDigest: sha256:c0e9560cda118f9ec63ddefb4a173a2b2a0347082d7dff7dc14272e7841a5b5aStatus: Downloaded newer image for alpine:latestdocker.io/library/alpine:latest
After pulling the image, you can see that a new 6b2b93d3f has been added to the diff,layer,mnt directory. Catalogue. Where:
6b2b93d3f under diff. The directory contains the relevant directories and files for the apline image.
6b2b93d3f under layers. The content in the file is empty because there is no parent mirror.
6b2b93d3f under mnt. The contents of the directory are empty because the container has not been started yet.
Root@cr7-ubuntu:/var/lib/docker/aufs# tree-L 3. ├── diff │ └── 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7 │ ├── bin │ ├── dev │ ├── etc │ ├── home │ ├── lib │ ├── media │ ├── mnt │ ├── opt proc Root │ ├── run │ ├── sbin │ ├── srv │ ├── sys │ tmp │ ├── usr │ var ├── layers │ └── 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7 # file is empty └── mnt └── 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7 # directory is empty after the container is created
Create a container using an apline image, but do not run the container yet.
Root@cr7-ubuntu:/var/lib/docker/aufs# docker create-it-- name aufs-test alpine965157ea214e48fdb8f10dbe1b254da442fff223496aacdc7ec2dd29b954b9d9
As you can see below, to create a container, you actually create a read-write layer (container layer), which is 76a069867. Catalogue.
The 76a069867...-init directory in the diff directory is used to initialize the container environment and contains the initialized files. 76a069867... The directory is a layer that will not be written until the container is running, because the container is not running yet, so the directory is empty.
The new 76a069867...-init file in the layer directory stores the basic image 6b2b93d3f. The ID,76a069867 file stores the parent image 76a069867...-init and 6b2b93d3f. ID.
The corresponding federated mount directory is also created under the mnt directory, and the 76a069867...-init and 76a069867 directories are empty.
Root@cr7-ubuntu:/var/lib/docker/aufs# tree-L 3. ├── diff │ ├── 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7 │ │ ├── bin │ │ dev │ │ ├── etc │ │ ├── home │ │ ├── lib │ media mnt en26# opt Proc │ │ ├── root │ │ ├── run │ │ ├── sbin │ │ ├── srv │ │ ├── sys │ │ ├── tmp │ usr var 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0-init dev etc layers ├── 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7 │ ├── 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0 │ └── 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0-init └── mnt ├── 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7 ├── 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0 └── 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0-init
Check the relationship of ID under layers:
Root@cr7-ubuntu:/var/lib/docker/aufs/layers# lltotal 16drwx-2 root root 4096 Nov 9 22:16. / drwx- 5 root root 4096 Nov 9 10:30.. /-rw-r--r-- 1 root root 0 Nov 9 21:03 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7murrwyr Nov 9 22:16 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a5824a2c70e1ca0c0c05rwliclicliclichr-1 root root 65 Nov 9 22:16 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0-init# 6b2b9d3fece.. If it is a basic image, there is no ID for the parent image. The root@cr7-ubuntu:/var/lib/docker/aufs/layers# cat 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7# 76a069867...-init file stores the basic image 6b2b93d3f. The IDroot@cr7-ubuntu:/var/lib/docker/aufs/layers# cat 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0-init6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7# 76a069867 file stores the parent image 76a069867...-init and 6b2b93d3f. After the IDroot@cr7-ubuntu:/var/lib/docker/aufs/layers# cat 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c076a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0-init6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7root@cr7-ubuntu:/var/lib/docker/aufs/layers# starts the container
Start the container using docker start and observe the directory under aufs again:
The diff directory is the same as before.
The layer directory is the same as before.
The 76a069867 directory of the mnt directory has added the content of 3 directory merges in diff.
Root@cr7-ubuntu:/var/lib/docker/aufs# docker start aufs-testroot@cr7-ubuntu:/var/lib/docker/aufs# tree-L 3. ├── diff │ ├── 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7 │ │ ├── bin │ │ dev │ │ ├── etc │ │ ├── │ │ ├── lib │ media mnt │ │ ├── opt │ │ ├── proc │ │ ├── root │ │ ├── run │ │ ├── sbin │ │ ├── srv │ sys tmp usr var 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0-init ├── dev │ └── etc ├── layers │ ├── 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7 │ ├── 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0 │ └── 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0-init └── mnt ├── 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7 ├── 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0 │ ├── bin │ ├── dev │ ├── etc home lib media mnt │ ├── opt │ ├── proc │ ├── root │ ├── run │ ├── sbin │ ├── srv │ ├── sys │ ├── tmp │ ├── usr │ var 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0-init45 directories 3 files
Create a new aufs.txt file in the container and you can see that the aufs.txt file has been added to the 76a069867 directory in both diff and mnt.
Root@cr7-ubuntu:/var/lib/docker/aufs# docker exec aufs-test touch aufs.txtroot@cr7-ubuntu:/var/lib/docker/aufs# docker exec aufs-test ls-lartrtotal 64drwxr-xr-x 12 root root 4096 Oct 21 09:23 vardrwxrwxrwt 2 root root 4096 Oct 21 09:23 tmpdrwxr-xr-x 2 root root 4096 Oct 21 09:23 srvdrwxr-xr-x 2 root root 4096 Oct 21 09:23 rundrwx- 2 root root 4096 Oct 21 09:23 rootdrwxr-xr-x 2 root root 4096 Oct 21 09:23 optdrwxr-xr-x 2 root root 4096 Oct 21 09:23 mntdrwxr-xr-x 5 root root 4096 Oct 21 09:23 mediadrwxr-xr-x 2 root root 4096 Oct 21 09:23 homedrwxr-xr-x 7 root root 4096 Oct 21 09:23 usrdrwxr-xr-x 2 root root 4096 Oct 21 09:23 sbindrwxr-xr-x 7 root root 4096 Oct 21 09:23 libdrwxr-xr-x 2 root root 4096 Oct 21 09:23 bindrwxr-xr-x 15 root root 4096 Nov 10 03:16 etc-rwxr-xr-x 1 root root 0 Nov 10 03:16 .dockerenvdr-xr-xr-x 13 root root 0 Nov 10 03:17 sysdr-xr-xr-x 255 root root 0 Nov 10 03:17 procdrwxr-xr-x 5 root root Nov 10 03:17 dev-rw-r--r-- 1 root root 0 Nov 10 03:19 aufs.txtdrwxr-xr-x 25 root root 4096 Nov 10 03:19... drwxr-xr-x 25 root root 4096 Nov 10 03:19. Root@cr7-ubuntu:/var/lib/docker/aufs# tree-L 3. ├── diff │ ├── 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7 │ │ ├── bin │ │ ├── dev │ │ ├── etc │ │ ├── home │ │ ├── lib │ ── media │ │ ├── mnt │ │ ├── opt │ │ ├── proc │ │ ├── root │ │ ├── run │ │ ├── sbin srv sys tmp usr var 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0 │ │ └── aufs.txt │ └── 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0-init │ ├── dev │ └── etc ├── layers │ ├── 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7 │ ├── 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0 │ └── 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0-init └── mnt ├── 6b2b93d3feced2838351bad5a459ebc13a55eca45007692ca1622a0c30e986b7 ├── 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0 aufs.txt bin dev Etc │ ├── home │ ├── lib │ ├── media │ ├── mnt │ ├── opt │ ├── proc │ ├── root │ ├── run │ ├── sbin │ srv sys tmp usr │ └── var └── 76a069867e2f7a662dda1c9e8ec0e3df868319a51631a584824a2c70e1ca01c0-init45 directories 5 files
However, have you ever thought of this question: what if what I have to do now is to delete a file in the read-only layer?
To achieve this deletion, AuFS creates a whiteout file in the read-write layer that "obscures" the files in the read-only layer. For example, if you delete a file called foo in the read-only layer, the delete actually creates a file called .wh.foo in the read-write layer. In this way, when the two layers are jointly mounted, the foo file will be "obscured" and "disappear" by the .wh.foo file. This function is the mount mode of "ro+wh", which means read-only + whiteout. I like to translate whiteout vividly as "White Barrier".
AUFS manual demonstration prepare demonstration directory and file root@cr7-ubuntu:/tmp/aufs# tree. ├── diff │ ├── container # container layer directory │ │ └── container.txt │ ├── image1 # image layer directory │ │ └── image1.txt │ └── image2 # image layer directory │ └── image2.txt └── mnt5 directories, 3 files create AUFS federated file system
Use the mount command to create a file system of type AUFS, as follows:
Root@cr7-ubuntu:/tmp/aufs# mount-t aufs-o dirs=./diff/container/:./diff/image1/:./diff/image2/ none. / mnt/
When the mount command creates an AUFS-type file system, it should be noted here that the first colon of the dirs parameter defaults to read-write permission, and the subsequent directories are read-only permission, which is consistent with the mode in which the Docker container uses AUFS.
After executing the above command, mnt becomes the federated mount directory of AUFS. We can use the mount command to view the AUFS file system that has been created:
Root@cr7-ubuntu:/tmp/aufs# mount-t aufsnone on / tmp/aufs/mnt type aufs (rw,relatime,si=1448e4c4c7bc84)
Every time we create an AUFS file system, AUFS will generate an ID for us. The ID will create a corresponding directory in / sys/fs/aufs/, and you can view the file mount permissions in this ID directory.
Root@cr7-ubuntu:/tmp/aufs# cat / sys/fs/aufs/si_1448e4c4c7bc84/*/tmp/aufs/diff/container=rw/tmp/aufs/diff/image1=ro/tmp/aufs/diff/image2=ro646566/tmp/aufs/diff/container/.aufs.xino
You can see that the permission of the container directory is rw (for read-write), and the permission for image1 and image2 is ro (for read-only). To verify that you can see everything in the container, image1, and image2 directories under the mnt directory, let's look at the mnt directory using the ls command:
Root@cr7-ubuntu:/tmp/aufs# ls mnt/container.txt image1.txt image2.txt
The directory structure at this time:
Root@cr7-ubuntu:/tmp/aufs# tree. ├── diff │ ├── container │ │ └── container.txt │ ├── image1 │ │ └── image1.txt │ └── image2 │ └── image2.txt └── mnt # mnt directory contains ├── container.txt ├── image1.txt └── image2.txt5 directories, 6 files
You can see that all the mirror layer and container layer files we prepared have appeared in the mnt directory. Let's verify the write-time replication of AUFS.
Verify write-time replication of AUFS
Write-time copy of AUFS means that only when a file needs to be modified will the file be copied from the mirror layer to the container layer. Let's verify this process by modifying the contents of the joint mount directory mnt.
We use the following command to modify the image1.txt file in the mnt directory:
Root@cr7-ubuntu:/tmp/aufs# echo "Hello, Image layer1 changed!" > mnt/image1.txt
Then let's look at the contents of the image1/image1.txt file:
Root@cr7-ubuntu:/tmp/aufs# cat diff/image1/image1.txtHello,Image layer1!
It is found that the image1.txt file of the Mirror layer has not been modified. Then let's look at the contents of the image1.txt file corresponding to the "container layer":
Root@cr7-ubuntu:/tmp/aufs# cat diff/container/image1.txtHello, Image layer1 changed!
It is found that AUFS automatically creates the image1.txt file in the "container layer", and the content is what we just wrote. The directory structure at this time:
Root@cr7-ubuntu:/tmp/aufs# tree. ├── diff │ ├── container │ │ ├── container.txt │ │ └── image1.txt # automatically created image1.txt file │ ├── image1 │ │ └── image1.txt │ └── image2 │ └── image2.txt └── mnt container.txt image1.txt image2.txt5 directories, 7 files to here I believe that you have a deeper understanding of "what is the working principle of AUFS?" you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.