Docker文件系统总结

89 篇文章 1 订阅
84 篇文章 4 订阅

https://blog.csdn.net/github_33873969/article/details/83414430

https://www.cnblogs.com/sammyliu/p/5931383.html
参考资料:
1,链接:https://www.jianshu.com/p/731aa34fc8da

一个典型的 Linux 系统要能运行的话,它至少需要两个文件系统:

    boot file system (bootfs):包含 boot loader 和 kernel。用户不会修改这个文件系统。实际上,在启动(boot)过程完成后,整个内核都会被加载进内存,此时 bootfs 会被卸载掉从而释放出所占用的内存。同时也可以看出,对于同样内核版本的不同的 Linux 发行版的 bootfs 都是一致的。
    root file system (rootfs):包含典型的目录结构,包括 /dev, /proc, /bin, /etc, /lib, /usr, and /tmp 等再加上要运行用户应用所需要的所有配置文件,二进制文件和库文件。这个文件系统在不同的Linux 发行版中是不同的。而且用户可以对这个文件进行修改。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191225145258460.png)
rootfs/boofs

Linux 系统在启动时,roofs 首先会被挂载为只读模式,然后在启动完成后被修改为读写模式,随后它们就可以被修改了。

    所有 Docker 容器都共享主机系统的 bootfs 即 Linux 内核
    每个容器有自己的 rootfs,它来自不同的 Linux 发行版的基础镜像,包括 Ubuntu,Debian 和 SUSE 等
    所有基于一种基础镜像的容器都共享这种 rootfs

aufs:(Ubuntu/debian默认)
AUFS (AnotherUnionFS) 是一种Union FS,简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统。Aufs driver是Docker最早支持的driver,但是aufs只是Linux内核的一个补丁集,而且不太可能会被加入到Linux内核中。但是由于aufs是唯一一个可以实现容器间共享可执行代码和运行库的storage driver,所以当你跑成千上百个拥有相同程序代码或者运行库的时候,aufs是个相当不错的选择。(记得安装linux-image-extra-*的kernel包)

device mapper:(CentOS/RH默认)
Device mapper是Linux 2.6内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略。
Device mapper driver会创建一个100G的简单文件包含你的镜像和容器。每一个容器被限制在10G大小的卷内, 可以调整。
你可以在启动Docker daemon时用参数-s 指定driver:docker -d -s devicemapper。

Btrfs:
Btufs driver 在Docker build时可以很高效。但是跟device mapper一样不支持设备间共享存储。

一:两个基本条件

一个典型的 Linux 系统要能运行的话,它至少需要两个文件系统:

boot file system (bootfs):包含 boot loader 和 kernel。用户不会修改这个文件系统。实际上,在启动(boot)过程完成后,整个内核都会被加载进内存,此时 bootfs 会被卸载掉从而释放出所占用的内存。同时也可以看出,对于同样内核版本的不同的 Linux 发行版的 bootfs 都是一致的。
root file system (rootfs):包含典型的目录结构,包括 /dev, /proc, /bin, /etc, /lib, /usr, and /tmp 等再加上要运行用户应用所需要的所有配置文件,二进制文件和库文件。这个文件系统在不同的Linux 发行版中是不同的。而且用户可以对这个文件进行修改。

在这里插入图片描述
Linux 系统在启动时,roofs 首先会被挂载为只读模式,然后在启动完成后被修改为读写模式,随后它们就可以被修改了。

所有 Docker 容器都共享主机系统的 bootfs 即 Linux 内核
每个容器有自己的 rootfs,它来自不同的 Linux 发行版的基础镜像,包括 Ubuntu,Debian 和 SUSE 等
所有基于一种基础镜像的容器都共享这种 rootfs

aufs:(Ubuntu/debian默认)
AUFS (AnotherUnionFS) 是一种Union FS,简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统。Aufs driver是Docker最早支持的driver,但是aufs只是Linux内核的一个补丁集,而且不太可能会被加入到Linux内核中。但是由于aufs是唯一一个可以实现容器间共享可执行代码和运行库的storage driver,所以当你跑成千上百个拥有相同程序代码或者运行库的时候,aufs是个相当不错的选择。(记得安装linux-image-extra-*的kernel包)

device mapper:(CentOS/RH默认)
Device mapper是Linux 2.6内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略。
Device mapper driver会创建一个100G的简单文件包含你的镜像和容器。每一个容器被限制在10G大小的卷内, 可以调整
你可以在启动Docker daemon时用参数-s 指定driver:docker -d -s devicemapper。

Btrfs:
Btufs driver 在Docker build时可以很高效。但是跟device mapper一样不支持设备间共享存储。
二:两种存储方式
在这里插入图片描述

数据卷

数据卷即是我们可以通过-v 参数将主机目录或者主机设备挂载在我们的docker container中,这种方式是在I/O传输中最快的方式,因为不用通过docker文件系统,直接到达主机目录,适用于数据持久化和大文件传输。下面是数据卷系统的一览图:
在这里插入图片描述
顺带一提的是,有不少研究docker存储系统与PM(持久化内存)结合的论文,都是用数据卷来进行研究。
从上面的volume存储层次可以看到:
Data Volume(数据卷) --> Backing File system(XFS,EXT4,etc.) -->就直接到了主机的设计(逻辑卷+物理卷)–> 到设备

2.不使用数据卷-两个文件系统的交互

如果不使用数据卷的话,就要通过一次的Storage Driver。由于有两种不同的文件系统,分别针对不同linux的发行版来定制,我们所采用的系统是centos,所以就以devicemapper为例:
在这里插入图片描述
对于Docker来说,devicemapper存储驱动直接控制的是block device,我们利用LVM将block device视为我们的物理卷,然后进行对于不同的存储层分出逻辑卷来进行操作。
所以,针对于Docker 文件系统的层次,先由的APP -> Docker本身的分层文件系统的相关机制 -> 然后再到Backing File System(我们要针对block device 进行刷盘的操作):EXT4 -> 然后才是我们分出的逻辑卷的block device。

接下来就是我们的Host机,我们先来做一个验证,验证host上的块设备:

在这里插入图片描述
Host机中,可以看到有loop1这个块设备,然后下面每一个挂载上去的子设备都是一个container,即每一个container的存储实际上是在对docker进行一个挂载。
在这里插入图片描述
这是在Host机上面的所对应的两种映射方式,一个Direct-LVM ,一个Loop-LVM
在这里插入图片描述
在Loop-LVM情况下,对于docker机来说的device,对于host机就成为了一个Data,MetaData两个文件。
如果是文件,那自然是要通过Host机的相关文件系统,才能到我们实际的SSD设备。
Direct-LVM可以直接拿Host机的块设备来使用,但不提供持久化的功能。

三:Docker使用的aufs文件系统

AUFS 是一种 Union File System(联合文件系统),又叫 Another UnionFS,后来叫Alternative UnionFS,再后来叫成高大上的 Advance UnionFS。所谓 UnionFS,就是把不同物理位置的目录合并mount到同一个目录中。UnionFS的一个最主要的应用是,把一张CD/DVD和一个硬盘目录给联合 mount在一起,然后,你就可以对这个只读的CD/DVD上的文件进行修改(当然,修改的文件存于硬盘上的目录里)。

关于 AUFS 的几个特点:

AUFS 是一种联合文件系统,它把若干目录按照顺序和权限 mount 为一个目录并呈现出来
默认情况下,只有第一层(第一个目录)是可写的,其余层是只读的。
增加文件:默认情况下,新增的文件都会被放在最上面的可写层中。
删除文件:因为底下各层都是只读的,当需要删除这些层中的文件时,AUFS 使用 whiteout 机制,它的实现是通过在上层的可写的目录下建立对应的whiteout隐藏文件来实现的。
修改文件:AUFS 利用其 CoW (copy-on-write)特性来修改只读层中的文件。AUFS 工作在文件层面,因此,只要有对只读层中的文件做修改,不管修改数据的量的多少,在第一次修改时,文件都会被拷贝到可写层然后再被修改。
节省空间:AUFS 的 CoW 特性能够允许在多个容器之间共享分层,从而减少物理空间占用。
查找文件:AUFS 的查找性能在层数非常多时会出现下降,层数越多,查找性能越低,因此,在制作 Docker 镜像时要注意层数不要太多。
性能:AUFS 的 CoW 特性在写入大型文件时第一次会出现延迟。

可见在一个Linux 系统之中,

所有 Docker 容器都共享主机系统的 bootfs 即 Linux 内核
每个容器有自己的 rootfs,它来自不同的 Linux 发行版的基础镜像,包括 Ubuntu,Debian 和 SUSE 等
所有基于一种基础镜像的容器都共享这种 rootfs

关于 Docker的分层镜像,除了 aufs,docker还支持btrfs, devicemapper和vfs,你可以使用 -s 或 –storage-driver= 选项来指定相关的镜像存储。在Ubuntu 14.04下,Docker 默认 Ubuntu的 AUFS。因为 AUFS 还没有进入Linux 内核主干的原因,RedHat 上使用的是 devicemapper。

我们可以在 docker info 命令的输出中查看所使用的存储驱动:

Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 19
Dirperm1 Supported: false

以一个正在运行着的 Docker 容器为例,其镜像有13层:

“RootFS”: {
“Type”: “layers”,
“Layers”: [
“sha256:1154ba695078d29ea6c4e1adb55c463959cd77509adf09710e2315827d66271a”,
“sha256:528c8710fd95f61d40b8bb8a549fa8dfa737d9b9c7c7b2ae55f745c972dddacd”,
“sha256:37ee47034d9b78f10f0c5ce3a25e6b6e58997fcadaf5f896c603a10c5f35fb31”,
“sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef”,
“sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef”,
“sha256:b75c0703b86b8ccbdc1f1b28b4982774768861ac250f83bdb940b1e90291f302”,
“sha256:5c121779bb29172c628a21087ea8ced766959da2f223c8b6bd4ffe943ace43d8”,
“sha256:3ee91c5cb95b01496b4afdc721ba7fd3c22e0e5e2f3e9e70d3f8579b5082d4f3”,
“sha256:6bbb1d0f845289217e20b66697fa7d651394d89983b0f5a89b88f037194476fe”,
“sha256:b44b0832d4c6bf33122ce3aa896b133df88275e6d20663a9bf2d941f764ac1fd”,
“sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef”,
“sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef”,
“sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef”
]
}

从 AUFS 的角度,可以看到有一个可写的容器层和14个只读的镜像层:

root@docker1:/sys/fs/aufs/si_ab487e40195df24f# cat *
/var/lib/docker/aufs/diff/2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab=rw #可写的容器层
/var/lib/docker/aufs/diff/2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab-init=ro+wh #本层及以下是只读的镜像层
/var/lib/docker/aufs/diff/5472f8388f9a61f6bd84498201a5ad71a2ec88cda16c42a3a1da7c30da45f102=ro+wh
/var/lib/docker/aufs/diff/61dcf0881e790bf52ec555727b58641791adeefadcc7abc2a77fd228bde1371a=ro+wh
/var/lib/docker/aufs/diff/f68672aaf17dd158aabc635b2d8d459d79db1cd5ff38bf3834fe8f9c7a05235e=ro+wh
/var/lib/docker/aufs/diff/45818d286499870412357d66eb6af951699f89db785c7c6a242d2e1ac99734f9=ro+wh
/var/lib/docker/aufs/diff/b2188d5c09cfe24acd6da5ce67720f81138f0c605a25efc592f1f55b3fd3dffa=ro+wh
/var/lib/docker/aufs/diff/85cb840562788e1b458e68265e62fd2da9d0d7e737256500e8a276bcb237183c=ro+wh
/var/lib/docker/aufs/diff/c18ba8efcb455e97f6aabe3985b147f6a37b8f5ad090373e88ddd326b4f90896=ro+wh
/var/lib/docker/aufs/diff/25de7dcc3a06f0caa3c701d4ed6c62f03e0757f6d477cc822db6e884bb366441=ro+wh
/var/lib/docker/aufs/diff/ad9e831217594cdfecd5e824690b0e52f2e16d6e2bb39b7143e66d467150cfe8=ro+wh
/var/lib/docker/aufs/diff/56d37c8eecd8be9ba13e07e1486e7a6ac2f0aa01f8e865ee6136137369d8d8a0=ro+wh
/var/lib/docker/aufs/diff/31bc6290457af4e560a3103020c85fbb5dfcfb201b0662a33165260529f87c07=ro+wh
/var/lib/docker/aufs/diff/e104672666119006648d0b82988c49527e52c64629750c5c9adde88acc790682=ro+wh
/var/lib/docker/aufs/diff/7a085e415855435121fb7837c26a5e951f622bc69364d9228d409a4929b627e1=ro+wh

根据上面 AUFS 的定义,容器的文件系统是从 14 个只读镜像层和1个可写容器层通过 AUFS mount 出来的。示意图如下:
在这里插入图片描述
这种分层文件系统可以通过官网的图来清晰的展示出来:
在这里插入图片描述

做一些实验:

(1)在容器中创建一个文件,该文件会被创建在可写的容器层中

root@docker1:/var/lib/docker/aufs/diff# find -iname createdbysammy
./2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab/opt/webapp/createdbysammy
root@docker1:/var/lib/docker/aufs/diff# ls -lt
total 60
drwxr-xr-x 9 root root 4096 Oct 4 22:37 2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab
drwxr-xr-x 6 root root 4096 Oct 1 11:56 2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab-init

(2)修改一个镜像层中的文件

修改前,文件 /etc/apt/sources.list 出现在两个层中:

root@docker1:/var/lib/docker/aufs/diff# find -iname sources.list
./f68672aaf17dd158aabc635b2d8d459d79db1cd5ff38bf3834fe8f9c7a05235e/etc/apt/sources.list
./b2188d5c09cfe24acd6da5ce67720f81138f0c605a25efc592f1f55b3fd3dffa/etc/apt/sources.list

在容器中对它进行修改后,它被拷贝到了容器层然后被修改了:

root@docker1:/var/lib/docker/aufs/diff# find -iname sources.list
./f68672aaf17dd158aabc635b2d8d459d79db1cd5ff38bf3834fe8f9c7a05235e/etc/apt/sources.list
./2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab/etc/apt/sources.list
./b2188d5c09cfe24acd6da5ce67720f81138f0c605a25efc592f1f55b3fd3dffa/etc/apt/sources.list

而另外两个层中的文件保持了不变。这说明了 AUFS 的 CoW 特性。

(3)删除容器层中的文件

容器中的文件 ./usr/local/lib/python2.7/dist-packages/itsdangerous.py 位于 56d37c8eecd8be9ba13e07e1486e7a6ac2f0aa01f8e865ee6136137369d8d8a0 层中,这是一个只读层。

在容器内删除它:

root@fa385836d5b9:/# find -iname itsdangerous.py
./usr/local/lib/python2.7/dist-packages/itsdangerous.py
root@fa385836d5b9:/# rm ./usr/local/lib/python2.7/dist-packages/itsdangerous.py
root@fa385836d5b9:/# find -iname itsdangerous.py

然后,容器层中出现了一个 .wh 文件,而镜像层中的文件保持不变:

root@docker1:/var/lib/docker/aufs/diff# find -iname *itsdangerous.py
./56d37c8eecd8be9ba13e07e1486e7a6ac2f0aa01f8e865ee6136137369d8d8a0/usr/local/lib/python2.7/dist-packages/itsdangerous.py
./2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab/usr/local/lib/python2.7/dist-packages/.wh.itsdangerous.py

在手工将 .wh 文件删除后,文件就会再次回到容器中。

rm ./2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab/usr/local/lib/python2.7/dist-packages/.wh.itsdangerous.py

root@fa385836d5b9:/# find -iname itsdangerous.py
./usr/local/lib/python2.7/dist-packages/itsdangerous.py

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值