AUFS is a union File System in which the so-called UnionFS is merging directories of different physical locations into the same directory. One of the main applications of UnionFS is to put a CD/DVD and a hard disk directory together with Mount, and then you can modify the files on this read-only CD/DVD (of course, the modified files are stored in the directory on the hard disk).
Aufs also called another UnionFS, later called Alternative UnionFS, later may feel not enough domineering, called into advance UnionFS. A Junjiro Okajima (Okayama Lang), developed in 2006, Aufs completely rewritten the early UnionFS 1.x, primarily for reliability and performance, and introduced new features such as load balancing for writable branches. Aufs in the use of fully compatible UNIONFS, and than the previous UnionFS in stability and performance are much better, later UnionFS 2.x began to copy the function of Aufs. But he did not go into the Linux backbone, because Linus, basically because the code is more than the volume, and write rotten (compared to only 3000 rows of union mount and 10000 rows of UnionFS, and other average only 6000 lines of code around the VFS, Aufs actually has 30000 lines of code), so, Okayama constantly improve the code quality, constantly submitted, and constantly rejected by Linus, so, to today aufs are still not into the Linux backbone (today you can see AUFS code is actually OK, than the OpenSSL good n times, Either Linus the quality of the code is very high, or Linus is not like Aufs).
However, fortunately there are many distributions are used aufs, such as: Ubuntu 10.04,debian6.0, Gentoo Live CD support Aufs, so, also OK.
Well, after all this gossip, let's just look at an example. (Environment: Ubuntu 14.04)
First, we built two catalogs (fruits and vegetables) and put some files in the two categories, with apples and tomatoes and vegetables with carrots and tomatoes.
12345678 |
$ tree . ├── fruits │ ├── apple │ └── tomato └── vegetables ├── carrots └── tomato |
Then, we enter the following command:
123456789101112 |
# 创建一个mount目录
$
mkdir mnt # 把水果目录和蔬菜目录union mount到 ./mnt目录中
$
sudo mount -t aufs -o
dirs
=.
/fruits
:.
/vegetables none .
/mnt
# 查看./mnt目录
$ tree .
/mnt
.
/mnt
├── apple
├── carrots
└── tomato
|
We can see that there are three files in the./mnt directory, Apple Apple, carrot carrots and tomato tomato. The catalogue of fruits and vegetables was union to the./mnt directory.
Let's change the contents of the file:
12345 |
$ echo mnt > . /mnt/apple $ cat . /mnt/apple mnt $ cat . /fruits/apple mnt |
In the above example, we can see that the contents of the./mnt/apple are changed, and the contents of the./fruits/apple are changed.
12345 |
$ echo mnt_carrots > . /mnt/carrots $ cat . /vegetables/carrots $ cat . /fruits/carrots mnt_carrots |
In the above example, we can see that we have modified the contents of the./mnt/carrots file, the./vegetables/carrots does not change, instead is the./fruits/carrots directory where the carrots file is found and the content is we're in./ Content in the Mnt/carrots.
That is, in the Mount Aufs command, we do not refer to its vegetables and fruits directory permissions, by default, the first (leftmost) directory on the command line is readable and writable, followed by all read-only. (in general, the first directory should be writable, and the latter should be read-only)
So, if we specify permissions like the following to Mount Aufs, you'll notice a different effect (remember to delete the above./fruits/carrots file first):
123456789 |
$
sudo mount -t aufs -o
dirs
=.
/fruits
=rw:.
/vegetables
=rw none .
/mnt
$
echo "mnt_carrots" > .
/mnt/carrots $
cat .
/vegetables/carrots
mnt_carrots
$
cat .
/fruits/carrots
cat
: .
/fruits/carrots
: No such
file or directory
|
Now, in this case, if we want to modify the./mnt/tomato file, then which file will be rewritten?
1234567 |
$ echo "mnt_tomato" > . /mnt/tomato $ cat . /fruits/tomato mnt_tomato $ cat . /vegetables/tomato I am a vegetable |
As can be seen, if there are duplicate file names on the Mount command line, the higher the priority is the more forward.
You can use this example to do a variety of experiments, I am here mainly to give you a perceptual knowledge, do not start the trial went on.
So what's the use of this unionfs?
Historically, there is a Linux distribution called Knoppix, which is mainly used for Linux demos, CD-ROM teaching, System first aid, and commercial product demonstrations, does not require hard disk installation, directly to the CD/DVD image on a writable storage device (such as a USB stick), in fact, That is, the CD/DVD file system and USB this writable system to the joint mount up, so that your image on the CD/DVD any changes will be applied to the USB flash drive, so you can make any changes to the contents of the CD/DVD, because the changes are on the USB stick, So you can't change the original thing.
We can use the imagination again, you can also put a directory, such as your source code, as a read-only template, and another your working directory to the Union together, and then you can make a variety of changes without fear of the source code to change the bad. A bit like an ad hoc snapshot.
Docker took UnionFS's imagination to the mirror of the container. Do you still remember I was in the introduction of Linux namespace in the previous article with Mount namespace and Chroot Cottage a mirror. Now that you've looked at this unionfs technique, you've learned that you can use a technique like unionfs to make layered mirrors.
The official document layer from Docker, which is a good showcase of the layered images that Docker has built with UnionFS.
For a layered image of Docker, in addition to the Aufs,docker support for Btrfs, Devicemapper and VFS, you can use the-s or –storage-driver= option to specify the associated mirrored storage. Under Ubuntu 14.04, docker default Ubuntu Aufs (under CentOS7, with Devicemapper, about Devicemapper, which I will explain in a later article) you can view each layer's image in the following directory:
1 |
/var/lib/docker/aufs/diff/ < id > |
After Docker executes (for example: Docker run-it Ubuntu/bin/bash), you can view the Aufs mount from the/sys/fs/aufs/si_[id] directory, here's an example:
1234567891011121314151617181920 |
#ls /sys/fs/aufs/si_b71b209f85ff8e75/
br0 br2 br4 br6 brid1 brid3 brid5 xi_path
br1 br3 br5 brid0 brid2 brid4 brid6
# cat /sys/fs/aufs/si_b71b209f85ff8e75/*
/var/lib/docker/aufs/diff/87315f1367e5703f599168d1e17528a0500bd2e2df7d2fe2aaf9595f3697dbd7
=rw
/var/lib/docker/aufs/diff/87315f1367e5703f599168d1e17528a0500bd2e2df7d2fe2aaf9595f3697dbd7-init
=ro+wh
/var/lib/docker/aufs/diff/d0955f21bf24f5bfffd32d2d0bb669d0564701c271bc3dfc64cfc5adfdec2d07
=ro+wh
/var/lib/docker/aufs/diff/9fec74352904baf5ab5237caa39a84b0af5c593dc7cc08839e2ba65193024507
=ro+wh
/var/lib/docker/aufs/diff/a1a958a248181c9aa6413848cd67646e5afb9797f1a3da5995c7a636f050f537
=ro+wh
/var/lib/docker/aufs/diff/f3c84ac3a0533f691c9fea4cc2ceaaf43baec22bf8d6a479e069f6d814be9b86
=ro+wh
/var/lib/docker/aufs/diff/511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
=ro+wh
64
65
66
67
68
69
70
/run/shm/aufs
.xino
|
You will see that only the topmost layer (branch) is the RW permission, and the others are read-only by the RO+WH permission.
For the AUFS configuration of Docker, you can see it in the/var/lib/docker/repositories-aufs file.
Some features of Aufs
Aufs has the features of Union FS, merging multiple directories into the same directory, and assigning permissions to each directory that needs to be merged, adding, deleting, and modifying the directories that have already been mount in real time. Plus, he can load balance between multiple writable branch/dir.
In the example above, we have seen the example of Mount of Aufs. Let's take a look at the permissions associated with the directory (branch) of the Union:
- RW indicates a writable, readable read-write.
- RO represents read-only, if you do not refer to the permissions, then in addition to the first RO is the default value, for the RO branch, it will never receive a write operation, and will not receive the operation to find Whiteout.
- RR represents real-read-only, unlike read-only, where RR tags are inherently read-only, so aufs can improve performance, such as not setting up inotify to check for file change notifications.
Permission, we see a term: whiteout, let me explain the term.
In general, the RO branch will have the properties of WH, such as "[DIR]=RO+WH". The so-called whiteout meaning, if a file deleted in the Union is actually located on a readonly branch (directory), then you will not see this file in the Union directory of Mount, But we can't make any changes on this read-only layer, so we need to whiteout the files in this readonly directory. The implementation of the Aufs Whiteout is achieved by creating a corresponding whiteout hidden file in a writable directory on the upper level.
Look at an example:
Suppose we have three directories and files as shown below (test is an empty directory):
123456789 |
# tree . ├── fruits │ ├── apple │ └── tomato ├── test └── vegetables ├── carrots └── tomato |
We have the following mount:
123456 |
# mkdir mnt # mount -t aufs -o dirs=./test=rw:./fruits=ro:./vegetables=ro none ./mnt # # ls ./mnt/ apple carrots tomato |
Now we have a whiteout hidden file under the test directory with the permission of RW. Wh.apple, you'll find out./mnt/apple This file disappears:
1234 |
# touch ./test/.wh.apple # ls ./mnt carrots tomato |
The above operation is the same as RM./mnt/apple.
Related terms
? Branch – is the list of all the directories to be union (the command-line arguments of the dirs I used above)
- ? Branch form a stack according to the Order of the Union, generally the top is writable, and the following are read-only.
- ? Branch stack can be modified after the mount, such as: Modify the order, add new branch, or delete the branch, or directly modify the permissions of branch
? whiteout and Opaque
- If a directory in UnionFS is deleted, it should not be visible, even if there is a directory in the underlying branch, it should not be visible.
- ? Whiteout is an upper directory that overrides the lower-level directory of the same name. Files used to hide lower-level branches are also used to prevent Readdir from entering lower-level branches.
- ? Opaque means not allowing any of the lower-level directories to show up.
- In the case of hidden low profile, Whiteout's name is ' .wh.<filename> '.
- ? In the case of blocking Readdir, the name is '. Wh. Wh.. Opq ' or '. Wh.__dir_opaque '.
Related issues
See above, you will have a few questions:
One, you might ask, what happens if a file is modified in the original place? will the directory of Mount be changed together? The answer is yes, or it can not be. Because you can specify a parameter called UDBA (full name: User's Direct Branch Access), this parameter has three values:
- Udba=none – after this parameter is set, the Aufs will run faster, because the changes that are not in the Mount directory aufs not be synchronized, so there is a problem with the data error.
- Udba=reval – After setting this parameter, AUFS will check to see if the file has been updated and, if so, will pull the changes to the Mount directory.
- udba=notify – This parameter allows Aufs to register inotify for all branch, which allows the aufs to have a higher performance in updating file modifications.
Second, if there are multiple RW branch (directories) are union up, then, when I create the file, Aufs will be created where? AUFS provides a parameter called Create that you can configure quite the creation strategy, with a few examples below.
CREATE=RR | Round−robin poll. The following example can see that a newly created file is written in three directories in turn
12345678910 |
hchen$
sudo mount -t aufs -o
dirs
=.
/1
=rw:.
/2
=rw:.
/3
=rw -o create=rr none .
/mnt
hchen$
touch .
/mnt/a .
/mnt/b .
/mnt/c
hchen$ tree
.
├── 1
│ └── a
├── 2
│ └── c
└── 3
└── b
|
Create=mfs[:second] | most−free−space[:second] Select the best branch of the available space. You can specify a time to check for free disk space.
Create=mfsrr:low[:second] Select a space greater than low branch, if the space is less than low, then AUFS will use Round-robin way.
More details about AUFS use parameters, you can directly under Ubuntu 14.04 through the man Aufs look at the various parameters and commands.
Performance of Aufs
Is the performance of Aufs slow? It's not slow either. Because Aufs will mount all the branches, it is slower to find the files. Because it's going to traverse all the branch. is an O (n) algorithm (obviously, this algorithm has a lot of room for improvement) So, the more branch, the slower the performance of finding files. However, once the AUFS has found the inode for this file, the original file is basically the same after the read and write operation.
Therefore, if your program runs under Aufs, the open and stat operations will have a noticeable performance degradation, the more branch, the worse the performance, but in Write/read operation, performance has not changed much.
IBM's Research center has given a very good performance report on Docker performance (PDF) "An Updated performance Comparison of Virtual Machinesand Linux Containers"
I cut two pictures out, the first one is sequential read and write, the second one is random read and write. There is basically no performance loss problem. And KVM is a bit slower to read and write at random (but what if the hard drive is SSD?). )
Sequential Read and write
Random Read and Write
Extended Reading
- Introduce UnionFS
- Union file Systems:implementations, part I
- Union file Systems:implementations, part 2
- Another union filesystem approach
- unioning file Systems:architecture, features, and design choices
(End of full text)
From:http://coolshell.cn/articles/17061.html
Docker Foundation Technology: AUFS