Docker动态挂载
事情由来
同事昨天问我docker文件可不可以启动容器的情况下动态挂载(即启动时的-v命令对应功能), 我告诉他可以试试如下方式完成这个需求, 举例如下:
- 容器加-v命令启动后, -v命令其实就是一个映射关系, 宿主机文件系统找到对应映射目录, 根据实现原理处理(如ln命令);
没试过, 不过因为记忆中之前有从宿主机的docker容器对应文件系统中拷贝过文件出来, 但由于两年之前的并不是很确定, 之后我们两人各自电脑找docker容器启动后对应的文件, 不过没找着, 当时想想还是算了, 不能实现也不是大事, 接着同时开始和我争论docker启动后的linux系统是否会在宿主中有对应文件, 还拿window虚拟机和我举例卷啊文件系统啊巴拉巴拉的(本人虽然前几年使用window系统, 也使用过多种虚拟机及虚拟机类似的沙箱应用, 并没有深究所以不能断定, 但是, 他没相关发现和结论他就断定他想的), 本人匪夷所思, 不想多说, 结果他不给台阶下戳戳逼人和旁边同时说出他就是故意玩我(差不多这个意思), 呵呵;
因此整理思考与实践成博文, 发给同事看, 关于写的东西正确与否, 看个人理解, 还是那句话, 不要相信计算机世界的一切.
关于对计算机世界的思考
最讨厌那种自以为是的人了, 比如某人说的浏览器原理, 还坚信自己说的是正确的, IT世界里所有的一切都是人写的, 应保持什么都不信的理念直到转行或死亡.
关于对卷与文件系统的思考
卷这个词一般出现在底层文件系统, 全称逻辑卷, 归根结底就是一块内存块, linux弱化了概念(内存不分块), 一般出现在window用户口中, 分区表将卷关联组成每个独立的文件系统, 当卷没有转文件系统时(文件系统有多种存在方式, 区别在于地址映射表和内存中数据结构不同)仅仅只是一个磁粒未被分化的内存块, 当格式化内存块(卷)时即初始化文件映射表的根及关键地址指向, 格式化后此时就是文件系统了.
某人说的docker启动后是跑在’卷’中的, 没有文件系统, 他怎么想和本人没有任何关系, 不过转行要趁早.
根据他说的话及补充的话, 他说的卷应该是指一个当前系统不能访问的文件系统格式(如window不能访问ext4格式的文件系统相似), 这里要阐明卷和文件系统不是一个东西, 文件系统是有地址映射表的卷, 我纠正他的话, 将卷转换成文件系统, 但理论知道文件系统的入口地址加使用特殊工具还是可以进到文件系统里面的(如部分linux系统需要使用ntfs-3g工具访问window系统的文件盘);
实验验证
查找启动中docker容器在宿主机的对应目录
经过查找与验证, 本人的目录在/var/lib/docker/overlay2
中, 其中文件名为imagesID, 由于docker的设计原理, 镜像是可以继承的, 因此验证可以使用find命令.
启动中的docker容器动态挂载的实现
本例以mount挂载方式示例, 思路来源于网上, 一切计算机系统只要需求合理都可以实现, 用别人东西无法实现? 不是鸡肋功能没做就是使用者没找对API, 还是找不到, 可能你发现了一个没人发现的价值不菲的IDEA, 不然开源社区和GOOGLE欢迎你.
HOSTPATH=/path/mount_point
REALPATH=$(readlink --canonicalize $HOSTPATH)
FILESYS=$(df -P $REALPATH | tail -n 1 | awk '{print $6}')
while read DEV MOUNT JUNK
do [ $MOUNT = $FILESYS ] && break
done </proc/mounts
while read A B C SUBROOT MOUNT JUNK
do [ $MOUNT = $FILESYS ] && break
done < /proc/self/mountinfo
SUBPATH=$(echo $REALPATH | sed s,^$FILESYS,,)
DEVDEC=$(printf "%d %d" $(stat --format "0x%t 0x%T" $DEV))
docker-enter mynginx sh -c "[ -b $DEV ] || mknod --mode 0600 $DEV b $DEVDEC"
docker-enter mynginx mkdir /tmpmnt
umount -v $HOSTPATH
# 卸载挂载点后执行/path/mount_point
docker-enter mynginx mount $DEV /tmpmnt