源本科技 | 码上会

Docker 数据存储

2025/12/24
100
0

学习目标

通过本课件,你将掌握:

  1. Docker 默认存储机制的局限性

  2. 两种核心持久化方案:Volumes 与 Bind Mounts 的原理与区别

  3. tmpfs 与命名管道(Named Pipes)的适用场景

  4. 如何根据实际需求选择正确的存储方式

  5. 常用命令与最佳实践


为什么需要外部数据存储?

容器默认存储的问题

  • Docker 容器的所有写入操作都发生在 可写层(writable layer)

  • 该层随容器生命周期存在:容器删除 → 数据永久丢失;

  • 无法被其他容器或主机进程直接访问;

  • 不适合存储数据库、日志、用户上传文件等需要持久化的数据

关键结论“容器是无状态的,数据必须外置。”


四种数据存储方案

类型

持久性

主机可见性

跨容器共享

性能

适用平台

Volumes

✅ 是

❌(Docker 管理)

⭐⭐⭐ 高

所有平台

Bind Mounts

✅ 是

✅(任意路径)

⭐⭐ 中

所有平台

tmpfs Mounts

❌ 否(内存)

⭐⭐⭐ 极高

Linux

Named Pipes

✅(Windows 特有)

✅(IPC)

Windows


Docker Volumes

核心特点

  • 由 Docker 管理:存储在 /var/lib/docker/volumes/(Linux)或 WSL2 路径(Docker Desktop);

  • 与主机文件系统解耦:不依赖特定目录结构;

  • 支持多容器共享

  • 可通过 CLI/API 管理(创建、列出、删除);

  • 支持 Volume Drivers:可对接云存储(如 AWS EBS、Azure Disk);

  • 性能优异:尤其在 Docker Desktop 上针对写密集型应用优化。

常用命令

# 创建命名卷
docker volume create my_volume

# 查看所有卷
docker volume ls

# 查看卷详情(含挂载路径)
docker volume inspect my_volume

# 删除未使用的卷(谨慎!)
docker volume prune

# 启动容器时挂载卷
docker run -d \
  --name my_app \
  -v my_volume:/app/data \
  nginx

docker-compose.yml 中使用:

services:
  db:
    image: postgres
    volumes:
      - db_data:/var/lib/postgresql/data

volumes:
  db_data:  # 声明命名卷

存储位置

  • Linux

    • /var/lib/docker/volumes/<volume_name>/_data

  • Docker Desktop (Windows/Mac):在文件资源管理器中输入:

    • \\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes

不要手动修改卷内容!应通过容器或 Docker API 操作。


Bind Mounts(绑定挂载)

核心特点

  • 直接映射主机任意目录或文件(需绝对路径);

  • 主机与容器双向同步:容器内修改 = 主机文件修改;

  • 非 Docker 进程也可访问

  • 无法通过 docker volume 命令管理

  • 存在安全风险:容器可意外修改 / 删除主机关键文件。

使用方式

# 挂载主机目录到容器
docker run -d \
  --name web_server \
  -v /home/user/app:/usr/share/nginx/html \
  nginx

# 挂载单个文件(如配置文件)
docker run -v /etc/localtime:/etc/localtime:ro alpine date

docker-compose.yml 中:

services:
  app:
    image: my-app
    volumes:
      - ./config.yaml:/app/config.yaml:ro  # 只读挂载

风险提示

  • 容器内进程拥有对挂载路径的完全读写权限

  • 若挂载 //etc 等系统目录,可能导致主机系统崩溃

  • 不推荐用于生产环境的数据持久化,除非明确控制访问范围。


其他存储方案

tmpfs Mounts(Linux)

  • 数据存储在主机内存中;

  • 容器停止 → 数据自动清除;

  • 用途:临时缓存、敏感信息(如会话密钥);

  • 不支持跨容器共享

docker run -d \
  --tmpfs /tmp \
  alpine

Named Pipes(Windows)

  • 用于容器与 Windows 主机间的进程间通信(IPC)

  • 常见于 .NET 应用与 Windows 服务交互;

  • 语法:-v \\.\pipe\<pipe_name>:\\.\pipe\<pipe_name>


使用时机

优先使用 Volumes 的场景

场景

说明

数据库存储

如 PostgreSQL、MySQL 数据目录

多容器共享数据

如 Web 服务器与日志分析器共享日志

备份与迁移

卷可轻松导出 / 导入到其他主机

云环境部署

通过 Volume Driver 对接云存储

开发环境数据持久化

避免每次重建容器丢失数据

可考虑 Bind Mounts 的场景

场景

说明

共享配置文件

/etc/resolv.conf、自定义 nginx.conf

源码热重载(开发)

将本地代码目录挂载到容器,实现即时更新

主机与容器协同工作

如 CI/CD 中挂载构建产物目录

主机文件系统结构固定

且确保无非 Docker 进程干扰

避免使用 Bind Mounts 的情况

  • 生产环境存储关键业务数据;

  • 主机目录权限复杂或路径不固定;

  • 安全合规要求高(如金融、医疗行业)。


最佳实践建议

  1. 默认选择 Volumes:除非有明确理由使用 Bind Mounts;

  2. 命名卷优于匿名卷:便于管理和追踪;

  3. 敏感数据勿存卷中:应使用 Docker Secrets(Swarm 模式)或外部密钥管理;

  4. 定期清理未使用卷docker volume prune(注意:会删除所有未挂载卷!);

  5. 开发 vs 生产分离

    • 开发:可使用 Bind Mounts 实现代码热更新;

    • 生产:使用预构建镜像 + Volumes 存储数据。


总结

对比项

Volumes

Bind Mounts

管理方式

Docker CLI/API

主机文件系统

路径依赖

需绝对路径

安全性

高(隔离)

低(可破坏主机)

可移植性

适用场景

数据持久化、多容器共享

配置共享、开发调试

记住“用 Volumes 存数据,用 Bind Mounts 挂配置。”


思考题

  1. 为什么在 Docker Desktop(Windows/Mac)上 Volumes 的性能优于 Bind Mounts?

  2. 如果一个容器同时挂载了 Volume 和 Bind Mount 到同一路径,会发生什么?

  3. 如何将一个 Volume 中的数据迁移到另一台 Docker 主机?


📘 延伸阅读