docker基础之镜像存储
/ / 点击Union File System
什么是Union File System
Union File System简称 UnionFS,是一种为Linux,FreeBSD,NetBSD操作系统设计的,把其他文件系统联合到一个挂载点的文件系统服务。它使用
branch将不同文件和目录透明地覆盖,形成一个单一一致的文件系统。这些branch都是readonly或read-write的,当对这个虚拟后的联合文件系统进行写操作时,系统是真正写到了一个新的文件中,看起来这个虚拟的联合文件系统是对任何文件进行操作的,但实际上并未改变原来的文件,unionFS使用了写时复制技术。写时复制(copy on write,简称CoW),也叫隐式共享,是一种对可修改资源实现高效复制的资源管理技术。主要思想:如果一个资源是重复的,没有任何修改,这时并不需要立即创建一个新资源,这个资源可以被共享,一旦有写操作发生时,就会将该资源复制一份,而且写操作发生在新copy的资源上。通过这种方式,可以减少未修改资源复制带来的消耗和硬盘存储的消耗。
Aufs
简介
aufs(Advanced multi layered unification filesystem)是一种支持联合挂载的文件系统,aufs将不同目录分层挂载到同一个目录下,每一层都是一个普通的文件系统。
读写操作
当需要读写一个文件时,会从最顶层开始向下寻找,本层没有,则根据层之间的关系到下一层找,直到找到第一个文件并打开它。
当写入一个文件时,如果文件不存在,则在读写层新建一个,否则向上边一个过程一样从顶层开始查找,直到找到最近的文件,aufs会将其复制到读写层进行修改。
当删除一个文件时,若文件仅存在于读写层,则可以直接删除,否则删除其在读写层的北方,再在读写层创建一个whiteout文件来标识文件不存在。
当新建一个文件时,若文件在读写层存在whiteout文件,则先删除之再新建,否则直接新建。
Device Mapper
简介
Device Mapper是一种从逻辑设备到物理设备的映射框架,通过使用它,用户可以很方便地根据自己的需要制定实现存储资源的管理策略。
它主要包括3个概念:映射设备、映射表、目标设备。
说明
docker使用Device Mapper的CopyOnWrite发生在块存储级别。Device mapper驱动会先在块设备上创建一个资源池,然后在资源池上创建一个带有文件系统的基本设备,所有镜像都是这个基本设备的快照,而容器则是镜像的快照。所以在容器里看到文件系统是资源池上基本设备的文件系统的快照,并不有为容器分配空间。当要写入一个新文件时,在容器的镜像内为其分配新的块并写入数据,这个叫用时分配。当要修改已有文件时,再使用CoW为容器快照分配块空间,将要修改的数据复制到在容器快照中新的块里再进行修改。Device mapper 驱动默认会创建一个100G的文件包含镜像和容器。每一个容器被限制在10G大小的卷内,可以自己配置调整。
DeviceMapper 根据使用的基础块设备是真正的块设备哈斯稀疏文件挂载的loop设备分为两种模式:direct-lvm模式和loop-lvm模式,两者性能差别很大。
Overlay
简介
Overlay主要目录结构:lower,upper,work,merge:
- lower:在docker中用于存放镜像分层文件,只读。可以有多个
- upper:在docker中用于存放修改的文件,新增、修改、删除等,对应docker存储的 diff目录
- work:
- merge:存放多个lower、upper合并后的文件和目录,对应docker的 merge目录
对联合挂载在merge目录下的文件操作规则:
- 新增:新增文件会直接将新增的文件写入到upper目录下
- 修改:如果对lower层中的文件修改,则会引起copy,文件copy到upper目录下,所有修改操作在upper目录下完成;如果对upper目录文件修改(包括新增的文件和已经从底层copy出的文件),则直接修改
- 删除:在upper目录中会对文件标记删除(使用ll查看文件标识为
c --- --- ---,正常文件第一个标识位为-,目录为d),合并到merge目录下的效果为删除。
大文件修改
对lower层大文件修改时,会产生一个
.file.swp(.前缀和.swp后缀)文件,修改文件在该文件操作,当执行保存时,首先将文件从lower层该文件复制到upper层中,命名为file~(在文件后加~后缀),然后将file~与.file.swp文件合并生成最终文件并删除file~。
本地测试显示,当保存文件时,新file和file~与lower层file曾同时共存。当文件从file~完全copy到file时,会被删除。
本地测试记录:
当使用vim打开大文件时,对应的upper目录中生成了.file.swp文件,当对其编辑时,所有修改操作都在该文件中记录(随着新增内容,swp文件大小随之改变);当执行保存时,upper中生成了file~文件,当该文件大小不再变动时查看大小,发现与lower层中文件大小一致,说明该文件为lower层文件的副本。此过程与Linux写大文件操作基本一致:本地生成.swp文件,然后直接将源文件重命名为
file~,再合并两者为最终文件,然后删除file~。在OverlayFS中区别为,file~文件在OverlayFS中是从底层复制的[当修改upper层文件时与Linux中写大文件操作一致],而在Linux中写大文件时file~是直接把源文件重命名的
自己动手使用Overlay
实验环境:centos7,内核:4.4.169-1.el7.elrepo.x86_64
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 文件路径: /app/overlayfs-test
目录结构:
.
├── layer1
│ ├── 1.txt
│ └── tmp.txt
├── layer2
│ ├── 2.txt
│ └── tmp.txt
├── layer3
│ ├── 3.txt
│ └── tmp.txt
├── layer4
│ ├── 4.txt
│ └── tmp.txt
├── mnt
├── upper
└── work
└── work
文件内容:
1. layer{n}/{n}.txt 内容里的内容为 n
2. layer{n}/tmp.txt 内容里的内容为 n执行命令:
1 | mount -t overlay -o lowerdir=/app/overlayfs-test/layer1:/app/overlayfs-test/layer2:/app/overlayfs-test/layer3:/app/overlayfs-test/layer4,upperdir=/app/overlayfs-test/upper,workdir=/app/overlayfs-test/work overlay /app/overlayfs-test/mnt |
命令格式:
(格式:mount -t overlay -o lowerdir=pwd1:pwd2,upperdir=pwd3,workdir=pwd4 overlay pwd5)格式说明:命令中
pwd{n}部分均为变量,根据自己挂载情况修改,lowerdir=pwd1:pwd2,当pwd1和pwd2中有同名文件,则显示的是pwd1中的文件。upperdir指定了upper文件的目录,workdir指定了work目录,最后一个参数指定了merge目录。执行后的目录结构:
1 | . |
如上, {n}.txt都挂载到了 mnt目录下,tmp.txt文件则只有一个,
cat mnt/tmp.txt输出1在mnt目录新增文件
x.txt输入x,删除1.txt,编辑2.txt输入x2,新的目录结构:
1 | . |
其中,
1.txt标记为删除,2.txt内容改为x2,x.txt是新增的文件在
mnt目录下,文件1.txt也确实被删除了,x.txt文件也添加进来了,2.txt内容也改为x2。反观layer1目录下,1.txt文件还存在,layer2目录中2.txt内容仍然为2