第七篇:《Docker 存储:Volume、Bind Mount 与 tmpfs》

容器默认的文件系统是临时的------容器删除后,其中所有数据都会丢失。对于数据库、日志、配置等需要持久化的数据,Docker 提供了三种存储方式:Volume、Bind Mount 和 tmpfs。本文将详细讲解三者的原理、适用场景以及具体操作方法,帮助你正确管理容器数据。

一、容器存储的临时性问题

Docker 容器的可写层与容器生命周期绑定:

容器运行时,所有对文件系统的修改都写入容器的可写层(位于宿主机 /var/lib/docker/overlay2/...)。

容器被删除时,可写层随之删除,数据永久丢失。

即使使用 docker commit 将容器保存为新镜像,也只能保留当时的状态,不适合频繁变化的数据。

因此,需要独立于容器生命周期的存储方案。

二、Docker 的三种存储挂载类型

三、Volume(卷)

Volume 是 Docker 推荐的持久化方式,由 Docker 完全管理,独立于容器。

3.1 基本操作

bash 复制代码
# 创建卷
docker volume create mydata

# 列出卷
docker volume ls

# 查看卷详情
docker volume inspect mydata

# 删除卷(只有未被任何容器使用才能删除)
docker volume rm mydata

# 删除所有未使用的卷
docker volume prune

3.2 使用卷挂载容器

bash 复制代码
# 运行容器时挂载卷(如果卷不存在,会自动创建)
docker run -d --name db -v mydata:/var/lib/mysql mysql

# 使用 --mount 语法(更显式)
docker run -d --name db --mount source=mydata,target=/var/lib/mysql mysql

# 只读挂载
docker run -d --name web --mount source=config,target=/etc/nginx/conf.d,readonly nginx

3.3 卷的备份与恢复

bash 复制代码
# 备份:启动一个临时容器,挂载源卷和目标目录,打包
docker run --rm -v mydata:/source -v $(pwd):/backup alpine tar czf /backup/mydata-backup.tar.gz -C /source .

# 恢复:创建一个新卷,解压备份文件
docker volume create newdata
docker run --rm -v newdata:/target -v $(pwd):/backup alpine tar xzf /backup/mydata-backup.tar.gz -C /target

3.4 适用场景

数据库(MySQL、PostgreSQL、MongoDB)的数据目录。

应用需要持久化的用户上传文件、日志文件。

需要在多个容器之间共享数据(例如一个卷挂载到多个容器)。

四、Bind Mount(绑定挂载)

Bind Mount 将宿主机上的任意目录或文件挂载到容器中。它依赖宿主机文件系统结构,因此可移植性较差,但在开发环境中非常方便。

4.1 基本用法

bash 复制代码
# 将当前目录挂载到容器的 /app
docker run -d --name dev -v $(pwd):/app node:18

# 使用 --mount 语法(推荐)
docker run -d --name dev --mount type=bind,source="$(pwd)",target=/app node:18

# 只读绑定
docker run -d --name dev --mount type=bind,source="$(pwd)",target=/app,readonly node:18

4.2 开发环境典型用法

在开发 Web 应用时,将代码目录挂载到容器内,修改代码后容器内立即生效(无需重建镜像):

bash 复制代码
# 项目结构
./myapp/
├── index.html
├── app.js
└── Dockerfile

# 启动容器,挂载代码目录
docker run -d -p 3000:3000 -v $(pwd):/app node:18 npm start

4.3 注意事项

路径必须使用绝对路径:$(pwd) 或完整路径。

文件权限:容器内进程的用户 ID 可能与宿主机不同,可能导致权限错误。可以通过 --user 或调整宿主机文件权限解决。

性能:Bind Mount 在 macOS/Windows 下通过文件共享机制(如 VirtioFS、gRPC FUSE)可能比 Volume 慢,但对开发来说影响不大。

五、tmpfs 挂载

tmpfs 将数据存储在内存中,不写入磁盘。容器停止或删除后,tmpfs 中的数据会丢失。

5.1 基本用法

bash 复制代码
# 挂载 tmpfs 到容器的 /tmp
docker run -d --name temp --tmpfs /tmp:rw,noexec,nosuid,size=100m alpine

# 使用 --mount 语法(仅 Linux)
docker run -d --name temp --mount type=tmpfs,destination=/tmp,tmpfs-size=100m alpine

5.2 适用场景

存放临时敏感数据(如 session、密码),避免写入磁盘。

提高频繁读写临时文件的性能(如编译缓存)。

测试环境中需要隔离文件系统但又不想持久化。

六、三种方式对比与选择

选择建议:

生产环境持久化数据 → Volume

开发环境代码热加载 → Bind Mount

临时敏感数据或缓存 → tmpfs

七、实战:MySQL 数据持久化与备份恢复

bash 复制代码
`# 1. 创建数据卷
docker volume create mysql-data

# 2. 启动 MySQL 容器
docker run -d --name mysql \
  -v mysql-data:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=root \
  mysql:8.0

# 3. 插入测试数据
docker exec -i mysql mysql -uroot -proot <<EOF
CREATE DATABASE test;
USE test;
CREATE TABLE t(id INT);
INSERT INTO t VALUES(1);
EOF

# 4. 备份卷数据
docker run --rm -v mysql-data:/source -v $(pwd):/backup alpine \
  tar czf /backup/mysql-backup.tar.gz -C /source .

# 5. 删除原容器和卷(模拟灾难)
docker stop mysql && docker rm mysql
docker volume rm mysql-data

# 6. 创建新卷并恢复
docker volume create mysql-data-new
docker run --rm -v mysql-data-new:/target -v $(pwd):/backup alpine \
  tar xzf /backup/mysql-backup.tar.gz -C /target

# 7. 启动新容器验证数据
docker run -d --name mysql-new -v mysql-data-new:/var/lib/mysql mysql:8.0
docker exec -it mysql-new mysql -uroot -proot -e "SELECT * FROM test.t`"

八、常见问题与解决

九、小结

本文详细介绍了 Docker 的三种存储方式。Volume 是生产环境持久化的首选;Bind Mount 适合开发调试;tmpfs 用于临时内存数据。理解它们的特性和适用场景,能够帮助你设计出数据可靠、易于管理的容器化应用。

相关推荐
阿米亚波1 小时前
【EVE-NG 实战】防火墙基础(VLAN · VRRP · NAT · ACL · 静态路由)
运维·网络·笔记·网络协议·计算机网络·网络安全·运维开发
日取其半万世不竭2 小时前
云服务器迁移怎么少停机?DNS 切换前后的完整清单
运维·服务器
FREEDOM_X2 小时前
Linux 多线程编程——总结
java·linux·运维·ubuntu
名字还没想好☜2 小时前
Docker 多阶段构建:把镜像从 1.2GB 砍到 15MB
运维·docker·容器·多阶段构建·镜像优化
祸心依旧2 小时前
Visual Studio 五月更新 —— 计划、评审、优化
运维·人工智能·visual studio
Web4Browser2 小时前
Headless 浏览器自动化适合哪些任务?巡检、截图和提交动作要分级
运维·前端·自动化
難釋懷3 小时前
Nginx浏览器强制缓存
运维·nginx·缓存
花和满楼3 小时前
K8s 1.36 ImageVolume GA:OCI 镜像不再只能跑容器
java·容器·kubernetes
大博士.J3 小时前
视频号主体违规与认证上限?正确的解决方式
运维·python·自动化
山东点狮信息科技有限公司3 小时前
企业级应用双模式部署架构设计:从单体到微服务的平滑演进
运维·微服务·架构