Docker底层文件系统UnionFS实践
容器文件系统的组织方式,决定了容器镜像的组织形式,允许通过”增量“的方式修改镜像里打包的文件(可以用git的提交来理解这个”增量“)。
Docker底层文件系统UnionFS实践
文章目录
- Docker底层文件系统UnionFS实践
虚拟化技术、容器技术都已经十分成熟,在日常工作中我们经常会使用到docker。容器技术的出现方便了广大开发者,并且,让企业在开发团队间协作上节省了一大笔钱,还提高了开发效率。
前置知识
本篇文章讲解docker的底层相关知识。针对docker的学习,我认为应该分阶段来讲。
因为这个正好对应了 “知道这个是什么东西” ,到 “会用这个东西,并且还很溜” ,再到 “完全了解这个东西” 的步骤。 书面一点的表达就是从 “应用” 到 “技术体系” 再到 “方法论” 的过程。
关于docker的入门教程可以看看docker中文文档:
docker中文文档 http://www.dockerinfo.net/document
言归正传,开始之前先提一句容器技术的心法: Namespace做了彼此隔离,Cgroup做了资源限制,rootfs做了文件管控
(针对的是Liunx容器) 。这是容器技术的核心,网上已经有很多相关的学习资料,可以查阅学习。本篇主要讲的是上述心法的第三部分,文件系统相关的知识。
rootfs文件管控的内容,一个知识点是mount文件挂载,这个决定容器与宿主机看到的文件系统情况,能够打包应用与对应的文件目录供容器使用;另外一个知识点就是容器文件系统的组织方式,这个决定了容器镜像文件的组织形式,允许通过”增量“的方式修改镜像里打包的文件(可以用git的提交方式来理解这个“增量”是什么情况)。
容器底层文件系统实现
这一篇文章主要介绍容器的文件系统(第二个知识点)。容器采用了UnionFS,即联合文件系统。
简单来说,就是将文件分层,有一层为只读(readonly),一层可写层(writeable)。通过这两层的性质,只读层在下,可写层在上,构成了容器运行时状态,多个容器可以用同一个镜像。如果文件发生改变,会从文件系统重复制一份出来,而不会影响之前的文件信息,复制出来的这个文件修改完成后,会向上叠加;没有发生改变的文件则可以容器共用,节省空间。
这个操作可以归纳为:写时复制、用时分配。具体怎么体现呢?后面实践可以看看。
在实践之前,先看看容器存储驱动,存储驱动是用来干什么的?就是完成UnionFS性质的方式,“通过什么方式做到写时复制、用时分配呢?”,不同的驱动实现的方式不一样。
容器的存储驱动有AUFS、OverlayFS、Device Mapper等等。
以OverlayFS为例,这个是一种联合系统。只有两层,只读层和可写层。
镜像层不可改变,容器层可写。
我们可以使用例子模拟一下,看看这样的结构怎么做到“写时复制、用时分配”。
OverlayFS实践
结构:
首先Overlay分为两层,lower层与upper层,其中lower为镜像层(只读),upper为容器层(可写)。
然后两层往上合并为文件Mount视图。
# 创建文件夹,lower、upper、merged、work
mkdir lower upper merged work
# 先写入内容
echo from lower > lower/in_lower.txt
echo from upper > upper/in_upper.txt
# 上面是lower upper各不同的,下面写入相同的
echo from lower > lower/in_same.txt
echo from upper > upper/in_same.txt
# 将文件夹联合
mount -t overlay overlay -o lowerdir=`pwd`/lower,upperdir=`pwd`/upper,workdir=`pwd`/work `pwd`/merged
tree .
.
├── lower
│ ├── in_lower.txt
│ └── in_same.txt
├── merged
│ ├── in_lower.txt
│ ├── in_same.txt
│ └── in_upper.txt
├── upper
│ ├── in_same.txt
│ └── in_upper.txt
└── work
└── work
# 从merged文件查看
cat merged/in_same.txt
cat merged/in_lower.txt
# 可以看到lower中的内容被upper中的内容遮盖了
接下来可以做一些尝试
# 在merged中增加
echo new from merge >> merged/in_same.txt # merged追加
echo from merge > merged/in_merge.txt # merged新建
echo "add in upper" > upper/in_upper.txt # upper追加
echo new file upper > upper/new_file_upper.txt # upper新建
# merge中的追加,会作用在upper上 - Dockerfile中增加一层(一行命令)的情况
# upper中新建,会体现在merged上 -
# merged中新建,会作用在upper上
# 在merged中删除
rm -i merged/in_same.txt # merged中删除
rm -i upper/new_file_upper.txt # upper中删除
# merged中删除文件,upper中文件还是存在
# upper中删除文件,merged中文件也消失
# 在merge中修改
vi upper/in_upper.txt
vi lower/in_lower.txt
cat upper/in_upper.txt
cat lower/in_lower.txt
# merged中修改,会直接修改到upper ;
# merged中修改in_lower , lower文件夹中不变,只会修改到upper文件夹中的in_lower
# 如果从upper直接修改,并不会带到merged中,并且merged中的也会和upper中的文件割裂开来(merge的改动不会带到upper); 而从merged中修改则可以作用到upper中
可以看到,联合文件系统的运行过程就是这种上下层控制的,形成上下覆盖映射,实现写时复制,用时分配的功能。
docker体现的方法论、技术体系、应用,都是十分值得学习的,推荐大家去深入学习并总结自己的东西出来。😃
以上实践的例子我放在了这里:
https://gitee.com/zeng-jinghao/kubernetes_stu/blob/master/1.docker_stu/
参考
更多推荐
所有评论(0)