Docker存储
概述
本文档详细介绍 Docker 存储的核心原理、存储驱动、数据持久化方案、卷(Volume)管理及常见问题排查,帮助掌握容器数据的存储、备份与迁移技巧。
核心概念:
| 概念 | 定义 | 说明 |
|---|---|---|
| 联合文件系统(UnionFS) | 将多个只读层(镜像层)和一个可写层(容器层)叠加,形成统一的文件系统视图 | 节省磁盘空间,多个容器共享镜像只读层 |
| 存储驱动(Storage Driver) | 实现 UnionFS 叠加逻辑的核心组件 | 影响存储性能、磁盘占用和兼容性 |
| 卷(Volume) | Docker 管理的宿主机目录,与容器生命周期解耦 | 存储路径:/var/lib/docker/volumes/ |
| 绑定挂载(Bind Mount) | 将宿主机任意目录挂载到容器内 | 灵活性高,但与宿主机耦合 |
| tmpfs 挂载 | 数据存储在内存中,容器停止后丢失 | 读写极快,适用于临时缓存 |
| 可写层(Writable Layer) | 容器启动时创建的临时可写层 | 生命周期与容器一致,性能低于卷 |
| 镜像层(Image Layer) | 镜像由多个只读层叠加组成 | 不可修改,修改需创建新层 |
Docker 数据持久化方案
Docker 提供 3 种核心数据持久化方式,按推荐优先级排序:卷(Volume)> 绑定挂载(Bind Mount)> tmpfs 挂载。
卷(Volume)
卷分为 3 类:
- 命名卷(Named Volume):用户指定名称,可重复使用、跨容器共享(推荐生产环境)
- 匿名卷(Anonymous Volume):Docker 自动生成随机名称,适合临时持久化
- 外部卷(External Volume):引用已存在的卷(NFS、云存储等),跨项目共享
创建卷
# 创建命名卷
docker volume create my-volume
# 创建 NFS 卷
docker volume create --driver local \
--opt type=nfs \
--opt o=addr=192.168.1.100,rw,noatime \
--opt device=:/nfs-share/docker-volumes \
my-nfs-volume
# 查看所有卷
docker volume ls
# 查看卷详情
docker volume inspect my-volume挂载卷
# 挂载命名卷
docker run -it --name test-container -v my-volume:/app/data nginx
# 匿名卷(自动生成名称)
docker run -it -v /app/logs nginx
# 只读挂载
docker run -it --name test-container -v my-volume:/app/data:ro nginx
# Docker Compose 挂载services:
app:
image: nginx
volumes:
- my-volume:/app/data
volumes:
my-volume:绑定挂载(Bind Mount)
将宿主机目录直接挂载到容器内,容器读写同步到宿主机。
# 挂载宿主机目录
docker run -it --name test-container -v /root/app/data:/app/data nginx
# 挂载单个文件
docker run -it --name test-container -v /root/app/nginx.conf:/etc/nginx/nginx.conf nginx
# 只读绑定挂载
docker run -it --name test-container -v /root/app/data:/app/data:ro nginx
# SELinux 权限适配(CentOS/RHEL)
docker run -it --name test-container -v /root/app/data:/app/data:Z nginxtmpfs 挂载
数据存储在内存中,容器停止后立即丢失。
# 基本 tmpfs 挂载
docker run -it --name test-container --tmpfs /app/tmp nginx
# 限制内存大小(100MB)
docker run -it --name test-container --tmpfs /app/tmp:size=100m nginx三种方案对比
| 对比维度 | 卷(Volume) | 绑定挂载(Bind Mount) | tmpfs 挂载 |
|---|---|---|---|
| 数据持久化 | ✅ 支持 | ✅ 支持(依赖宿主机) | ❌ 不支持 |
| 宿主机耦合度 | 低 | 高 | 中 |
| 权限管理 | Docker 自动处理 | 手动配置 | 无需配置 |
| 读写性能 | 高 | 高 | 极高 |
| 可移植性 | 高 | 低 | 无 |
| 适用场景 | 生产环境持久化 | 开发调试 | 临时缓存 |
卷管理常用命令
| 操作 | 命令 |
|---|---|
| 创建卷 | docker volume create <卷名> |
| 查看所有卷 | docker volume ls |
| 查看卷详情 | docker volume inspect <卷名> |
| 删除卷 | docker volume rm <卷名> |
| 删除所有未使用卷 | docker volume prune |
| 备份卷 | docker run --rm -v my-volume:/source -v $(pwd):/backup alpine tar czf /backup/backup.tar.gz -C /source . |
| 恢复卷 | docker run --rm -v my-volume:/target -v $(pwd):/backup alpine tar xzf /backup/backup.tar.gz -C /target |
| 查看卷占用空间 | docker system df -v |
Docker Compose 存储配置示例
services:
app:
image: nginx
volumes:
# 命名卷
- app-data:/app/data
# 绑定挂载
- ./config:/app/config:ro
# tmpfs
- type: tmpfs
target: /app/tmp
tmpfs:
size: 100M
volumes:
app-data:
# 外部卷
external: true
name: existing-volume常见问题与注意事项
容器数据丢失
- 确认是否使用了持久化存储(卷或绑定挂载)
- 检查容器启动命令是否包含
--rm(自动删除容器和可写层) - 确认卷是否被误删除:
docker volume ls
卷删除后数据恢复困难
- 卷删除前确保已备份数据
- 可使用
docker volume prune谨慎操作 - 定期备份重要卷数据
绑定挂载权限不足
- SELinux 系统需添加
:Z或:z参数 - 确认宿主机目录权限与容器用户匹配
- 检查宿主机目录是否存在
磁盘空间不足
# 查看 Docker 磁盘使用情况
docker system df
# 清理未使用的镜像、容器、卷、网络
docker system prune -a
# 清理所有未使用卷
docker volume prune卷迁移与备份
# 备份卷
docker run --rm -v source-volume:/source -v $(pwd):/backup alpine tar czf /backup/backup.tar.gz -C /source .
# 恢复卷
docker run --rm -v target-volume:/target -v $(pwd):/backup alpine tar xzf /backup/backup.tar.gz -C /target