5.2 卷、绑定挂载与tmpfs:数据的三种住法


5.2 卷、绑定挂载与 tmpfs:数据的三种住法

摘要:Docker 提供三种把宿主资源挂进容器的通道:卷由 Docker 统一管理、生命周期独立;绑定挂载指向宿主机任意路径;tmpfs 把数据放进内存。本节用可复现实验验证三者的行为差异,给出数据去向的决策表与数据库备份恢复的完整手法。

学习目标

  1. 用一条 -v 或 --mount 语法正确挂载三种存储
  2. 通过实验验证卷的持久性、绑定挂载的双向性、tmpfs 的易失性
  3. 完成卷的备份与恢复
  4. 按数据性质选择挂载方式并说明理由

卷:Docker 管理区里的正式住户

docker volume create pgdata docker run -d --name pg --mount source=pgdata,target=/var/lib/postgresql/data -e POSTGRES_PASSWORD=secret postgres:16

写入一些数据后做关键实验:

docker exec pg psql -U postgres -c "create table t1 as select 1 as v;" docker rm -f pg docker run --rm -v pgdata:/mnt alpine ls /mnt

容器删了,挂上同一个卷再看——数据分毫未动。卷的内容住在 Docker 管理区(/var/lib/docker/volumes/pgdata/_data),不依附任何容器。这就是"容器牛牛,数据长存"的实现基础。卷还有两个加分项:可被多个容器同时挂载(共享数据的正规途径),以及卷驱动机制可以把数据放到网络存储或云盘上(NFS、云厂商卷插件),让有状态服务迈出单机。

绑定挂载:住在你家客厅

docker run -d --name dev -v /home/me/project:/app -w /app mynode npm run dev

宿主机目录直通容器。你在编辑器里改代码,容器里的进程立刻看到——热更新开发的标配。代价也来自这份"直通":容器的行为依赖宿主机的路径布局,换台机器路径就不一定存在;性能取决于宿主文件系统(在 Docker Desktop 上还隔着虚拟机,macOS 上尤其慢);权限映射直来直去,容器内 root 写出来的文件宿主机上也是 root 属主。

卷与绑定挂载的语义差异用一个细节就能记住:挂载点若容器内原本有内容,卷会把镜像里的内容先复制进空卷,绑定挂载则直接用宿主目录遮蔽原内容。这就是数据库用绑定挂载偶尔出诡异初始化问题、用卷则一帆风顺的原因。

tmpfs:内存里的临时住户

docker run -d --name web --tmpfs /run/session:size=64m nginx:alpine

数据写在内存页上,容器一停就蒸发。两类用途:追求极致速度的临时中间产物(编译缓存、会话数据),以及不该落盘的机密——私钥、令牌,写进 tmpfs 至少不会在磁盘上留副本。

三者对照实验与决策表

维度 绑定挂载 tmpfs
存放位置 Docker 管理区 宿主机任意路径 内存
容器删除后 保留 保留(本来就在宿主) 消失
迁移到别机 方便(卷驱动可入云) 需要搬运路径 不适用
性能 原生文件系统 原生(桌面版打折) 最快
典型数据 数据库、消息队列 开发源码、配置文件 会话、机密

一句话决策:要活过容器生命周期的生产数据用卷;开发期代码同步用绑定挂载;机密与临时态用 tmpfs。唯一不要选的选项是把数据写进可写层。

数据从容器可写层搬到卷的完整路径

备份与恢复:卷的正确姿势

卷的数据不在容器里,但备份还得借助容器。标准手法是临时起一个容器挂载卷,把内容打包到宿主目录:

# 备份 docker run --rm -v pgdata:/data -v /home/me/backup:/backup alpine \ tar czf /backup/pgdata-$(date +%F).tar.gz -C /data . # 恢复到新卷 docker volume create pgdata2 docker run --rm -v /home/me/backup:/backup -v pgdata2:/data alpine \ tar xzf /backup/pgdata-2026-08-19.tar.gz -C /data

两条命令值得细品:备份容器同时挂了卷和宿主目录,充当数据搬运工;--rm 用完即焚不留痕迹。生产上把这两条挂进定时任务,卷数据就有了最基本的保障。更成熟的路线是卷驱动对接云盘快照,思路相同、粒度更细。

常见坑清单

卷挂了但数据丢了:检查是不是用了匿名卷却删容器时加了 -v 参数——docker rm -v 会连带删除匿名卷(命名卷不受影响)。匿名卷是 Dockerfile 里 VOLUME 指令暗地里创建的,数据库镜像常用它,用户却毫无感知。生产一律用命名卷,拒绝匿名卷。

绑定挂载后容器内文件属主不对:容器内进程 UID 与宿主文件属主不匹配。常见解法是构建镜像时创建与宿主相同 UID 的运行用户,或用 --user 运行时指定。

同挂一个卷的两个容器写坏数据:卷提供的是共享通道不是并发控制,两个数据库实例写同一个卷必然损坏。共享只适用于"一方写一方读"或应用层自带锁的场景。

本节要点回顾

  • 卷是生产数据唯一推荐住法:生命周期独立、可备份、可入云
  • 绑定挂载是开发利器、生产包袱:路径依赖与遮蔽语义要心里有数
  • tmpfs 管机密与临时态:不落盘本身就是安全属性
  • 匿名卷是暗雷:命名卷加定期备份是底线配置
  • 卷共享不等于并发安全,数据一致性归应用管

存储层收尾。下一章向上到编排层——当容器多到一屏放不下时,谁来指挥。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U