6. 为什么有这么多fs@dm
本节内容, 结合着后面的练习相当硬核, 看起来会比较吃力, 我本人的做法是先简单过了一遍内容(当然会有一些看不太明白的), 接着开始把练习走了一遍, 边走边思考跟镜像 / 容器之间的关联, 才能勉强明白这其中的意思
introduction
跟 aufs / ext4 这种文件系统不同, devicemapper 压根就不是一个文件系统, 在我的理解里, 这种东西只是一种"映射机制", 我们后面会见到 deivce + mapper的命名说明了, 你以为, 在你将一个dm设备挂载到指定路径上后, 你是在访问这个设备, 其实只是它帮你映射到另一个dm设备上了.
所以devicemapper底层到底是什么文件系统呢? 没人在乎, 它可以是ext4, 也可以是别的什么底层文件系统. 在容器里的你甚至都不知道你在往哪儿写, 你只知道你在往一个目录下写文件, 你不知道这个目录是被另一个设备挂载着. 你更不知道这个设备其实是个 dm. 你的文件早 就被映射到底层的某个磁盘里去了. 这就是devicemapper, 一个设备(目录, 设备被挂载到目录下)映射器, 不是任何文件系统, 是一个带有很多特性的设备映射器
我们从这一点出发可以展开思考, 既然映射方案是我们规定的, 那么理论上我们就可以在里面玩花样, 举个例子把, 如果我们想给每个用户10G磁盘空间让他随便搞. 那么我们可以专门把他那10G映射到指定磁盘上, 更进一步的, 我们可以规范化管理容器宿主机上占用的磁盘, 思路的确是一个好的思路
事实上, Linux下已经有一些逻辑卷(Volume) → 物理卷的映射方案
LVM2 / EVMS / dmraid , 而这些全都是基于 DeviceMapper 做的
制定一个映射逻辑
你要做的事情是制定映射策略, 那些逻辑卷? 怎么映射? 映射到地方可以是物理卷, 也可以是另一个逻辑卷, 进行嵌套映射下去 (这不是开玩笑, Docker容器的多层镜像, 底层只有两个物理卷, 上一层会映射到下一层, 下一层继续嵌套映射, 最终落在这两个物理卷上).
用户, 你需要负责: 制定映射逻辑
需要用到
dmsetup
(devicemapper-setup)工具, 与devicemapper库来创建一个dm设备
将一个dm 设备挂载到指定路径下
为dm设备挂载路径制作镜像
指定映射关系 etc.
内核, 需要负责执行这些规格策略, 具体的工作内容包含:
过滤&重定向 IO 请求
通过某些驱动插件, 转发 IO 请求到实际的物理卷上
关键技术
dm的关键技术有三个, 分别是:
CopyOnWrite: 这个大家都懂, 就是一般不复制, 只从源文件读, 只有在产生写请求的时候才会将源文件复制过来, 然后往复制品上写, 区别于 aufs 那种传统的整个文件复制的, dm 只复制一小块, 就一小块, 一个block , 64K, 如果不够就继续再复制一些别的
thin-provisioning [一种磁盘供给技术] : 理解这玩意儿, 你就去想想计算机里的虚拟内存技术, 或者云服务商嘴里的超售, 比如我分配给你size=N的大小 , 但我知道你绝对用不完, 你只可能用的比这少, 不可能用的比这多. 所以我们采取一种实报实销 的策略, 你要, 我就给你分配一些, 但总量, 是不会超过size=N的
snapshot[一种复制镜像层技术]: 这东西是, 基于当前数据创建一个副本出来, 令副本跟原件完全一模一样, 实现方式可以是直接复制, 也可以是使用指针, 修改文件的时候创建新文件, 并使用新文件覆盖旧文件, 达到不修改原件的效果
有了以上三种工具, 我们从上一层镜像(只读层)制作一个快照, 这个快照就是我们的读写层. 现在如果你想执行读操作, 快照会把我们重定向到镜像里, 并拉出源文件来. 如果想写, 就使用thin-provisioning技术, 一个block64K的分配磁盘来写.
总结
省空间: thin-provisioning贯穿始终, CoW不复制整个文件
速度: 通过映射的方式重定向
兼容性好: 已经合并进内核了, 基本都能用dm驱动
Reference
排名存在先后:
Last updated
Was this helpful?