网站首页 文章专栏 怎样在一个容器里(运行或者停止)挂载新的卷呢???
怎样在一个容器里(运行或者停止)挂载新的卷呢???
编辑时间:2021-05-27 17:28:24 作者:linxi 浏览量:504

当一个容器运行后,如果我们想再添加或者/删除挂载路径,怎么做呢?本文尝试了 3 种方法,第 3 种是推荐做法。


一、修改 container 的配置文件,重启容器

缩略图

 我们首先会想到去修改容器配置文件,如上图中 config.v2.json、hostconfig.json 这两个配置文件中挂载点数据,如将config.v2.json修改为我们想要的路径,然后保存,重启容器,但这样配置文件会被刷新

缩略图

缩略图

成功的方法:stop container -> edit config file -> restart docker service (所以,这种方法不可取)


二、通过 overlay2 存储,实现实时添加挂载路径

如果你对联合挂载技术有所了解,你就会想到此种方法。容器实际上是在联合文件系统(rootfs)上,创建了新层,每层保存的是 diff ,那么我们是否可以将宿主机路径(待挂载路径)软连接到 overlay2 的 diff 路径(最上层)下呢???

2.1  首先,我们要启动一个 container

缩略图

2.2  然后,我们要 docker inspect container,找到容器的最上层

缩略图

如上图,/var/lib/docker/overlay2/233d2007ef3255ecaab0ce7ba6161abff0f7927f3b9534d7b4101df7262b4910/diff

2.3  再到 diff 目录,创建文件夹 doot

缩略图

2.4  再将 doot 连接到宿主机的 /home/lxy(宿主机上执行)

ln -s  /home/lxy /var/lib/docker/overlay2/233d2007ef3255ecaab0ce7ba6161abff0f7927f3b9534d7b4101df7262b4910/diff/doot

2.5  进入容器查看 doot 目录,宿主机 /home/lxy 目录下文件都被链接到容器中了

缩略图

此种方法较为简单,但 block 设备,采用此种方法会失败(容器内相应目录,看不到文件,测试了nfs 挂载路径就无法看见)


三、进入容器命名空间操作实现

3.1  我们启动一个容器,不挂载任何路径缩略图

3.2  要挂载 nfs 的 /mnt 目录到容器,首先,查找 /mnt 的设备信息

缩略图

我们可以看到,/mnt 目录挂到 "/" 目录下了

3.2  再检查宿主机 /proc/self/mountinfo 目录,查看文件系统的子目录在哪

less /proc/self/mountinfo

缩略图

可以看见,"/" 目录对应的设备为 /dev/mapper/centos-root , 主、副设备号为 253、0

3.3  进入容器命名空间,创建设备

nsenter --target 1482552 --mount --uts --ipc --net --pid -- mkdir /dev/mapper

nsenter --target 1482552 --mount --uts --ipc --net --pid -- [ -b /dev/mapper/centos-root ] || mknod --mode 0600 /dev/mapper/centos-root b 253 0

注意:此处要找到容器进程PID,可用以下命令:

docker inspect --format {{.State.Pid}} <container_name_or_ID>

缩略图

此时,容器内有了centos-root 设备

3.4  我们再进入容器命名空间,创建挂载目标路径:/mnt

nsenter --target 1482552 --mount --uts --ipc --net --pid -- mkdir /mnt

缩略图

3.5  然后,将宿主机 /dev/mapper/centos-root 设备挂载到容器 /mnt 目录

nsenter --target 1482552 --mount --uts --ipc --net --pid -- mount /dev/mapper/centos-root /mnt缩略图

现在,容器可以访问宿主机/mnt目录对应的设备了,所以,再做一次简单的子目录绑定即可

缩略图

缩略图

3.6  子目录绑定,将容器 /mnt/mnt/ 挂载到 /inspurfs/test

nsenter --target 1482552 --mount --uts --ipc --net --pid -- mkdir -p /inspurfs/test

nsenter --target 1482552 --mount --uts --ipc --net --pid -- mount -o bind /mnt/mnt/ /inspurfs/test


3.6 此时,我们进入容器,会惊奇的发现,宿主机 /mnt 目录下的问文件被挂载进去了



参考文献:

https://www.cnblogs.com/jiangzhaowei/p/11843026.html

https://nanxiao.me/proc-self-mountinfo/

https://man7.org/linux/man-pages/man5/proc.5.html

https://blog.csdn.net/whatday/article/details/106354092

https://medium.com/kokster/mount-volumes-into-a-running-container-65a967bee3b5

https://blog.csdn.net/a1010256340/article/details/83088870

来说两句吧
最新评论