linux 发行版中在容器内访问热插拔 U 盘的分区内容

前言

UOS 如何实现自动将 U 盘挂载到指定目录中?这篇文章中,我描述了 UOS 自动挂载 U 盘到指定目录的方式,现有的发行版处理逻辑大致相同。

当挂载位置确定后,容器内的业务逻辑要访问 U 盘分区中的内容,看上去只需要映射宿主机目录到容器内就万事大吉了,实际测试却发现这种方式存在一个严重的问题,最后使用了 docker volume 来实现此需求,在本文中记录一下。

需求描述

项目功能开发需要支持自动将 U 盘挂载到某个业务文件夹中在 docker 容器内进行访问,需要调研现有方式。

-v 映射宿主机目录方式

操作方法

在 docker 容器创建时映射 U 盘挂载目录的上级目录,在这个场景中其位置是 /media/user。

测试情况与存在的问题

  1. 容器启动前 U 盘成功挂载,容器启动后能够在容器内看到 U 盘分区内容
  2. 容器启动后热插拔 U 盘,宿主机能够看到 U 盘挂载目录下的文件,容器内看不到,观察发现容器内部看到的目录跟宿主机上的目录不是同一个

volume 的尝试

操作方法

  1. 执行 docker volume 创建一个 bind 到 /media/user 的 docker 卷
  2. 容器创建时映射上述 docker 卷

测试情况与存在的问题

  1. 容器启动后,动态插拔 U 盘,能够在容器内观察到 U 盘挂载目录的创建与移除,创建后能够正常看到分区内容
  2. U 盘成功挂载后再启动容器,容器内看不到 U 盘挂载分区内容,宿主机中可以正常看到
  3. 容器启动后挂载 U 盘,能够正常访问分区内容,此时退出容器,U 盘被 docker 自动卸载,此后 docker volume 异常,容器内无法访问 U 盘分区内容,重新删除、创建 docker volume 部署容器后恢复

问题分析

docker volume 在容器退出后自动卸载是 docker 自身的逻辑,这个逻辑在我们的场景中带来的问题是 docker 容器内再也无法正常访问 U 盘挂载目录,那有什么方式能解决此问题呢?

下班路上突发奇想,如果有两个容器同时映射了同一个 docker volume,那其中一个退出另外一个在运行 docker 是否还会卸载 U 盘。

我的答案是不会,因为如果是这样的行为,那就对正常运行的容器功能造成了影响,实现侧可能实现为一个 reference,只有当没有人引用时才会卸载。

测试了下确实是这样的效果,于是创建了一个 docker 自动启动的最简容器,此容器映射了我们创建的 docker volume,此时业务容器退出也不会影响卷本身,这个容器的目的就是增加引用计数,就这样不完美的解决了这个问题。

volume vs 映射宿主机目录

虽然问题得到了解决,但是对于内部的原理并没有太多了解。不禁要问 volume 与直接映射宿主机目录的差别在哪里?

从观察到的现象上我发现有如下两点要素:

  1. 直接映射宿主机目录是静态的,容器启动前有目录内容,启动后就有目录内容,容器启动后,目录内动态的挂载,挂载后的新目录并不会映射到容器内
  2. docker volume 是动态的,需要有挂载与卸载的动作来触发 volume 动态映射目录,如果没有这个动作容器内也无法访问映射目录

具体内部原理还需要进一步研究,解决此问题已经绰绰有余。

总结

对某些技术原理的欠缺容易造成错误的判断,误认为它应该是怎么样,实际测试却发现它不是那样。有时候觉得问题已经无解了,其实只是自己对技术的掌握度相对欠缺不容易想到新的解决方案,此时应该跟同事讨论,看看大家有没有啥新的点子,对这些点子大胆尝试可能会有意料之外的结果。

相关推荐
Patrick_Wilson4 天前
从「改个端口」到 502:Next.js on k8s 的容器端口、Service 映射与 env 覆盖
docker·kubernetes·next.js
Suroy4 天前
DockerView-Go:用 Go 写一个终端 Docker 监控工具,顺便做了个 Web 仪表盘
docker
云恒要逆袭4 天前
运行你的第一个Docker容器
后端·docker·容器
宋均浩5 天前
# Docker 镜像瘦身实战:从 1.2G 到 80MB 的五个优化步骤
ci/cd·docker
程序员老赵6 天前
10 分钟部署 OpenCode:Docker 一键安装,浏览器打开就能用 AI 写代码(附完整命令与排错)
docker·容器·ai编程
WangMingHua1116 天前
LM Studio Docker 部署——本地大模型一键启动
docker
曲幽7 天前
别再用网页翻译看源码了!你的私人翻译神器LibreTranslate,部署避坑指南来了
python·docker·web·pot·translate·libretranslate·arogstranslate
武子康9 天前
调查研究-183 Apple container:Mac 上用轻量 VM 跑 Linux 容器,Swift 会改写本地容器体验吗?
docker·容器·apple
Alsn8612 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
程序员老赵12 天前
服务器没有桌面?Docker 跑个 Chrome,浏览器就能远程用
docker·容器·devops