💾 Docker 数据卷详解¶
约 1044 个字 123 行代码 1 张图片 预计阅读时间 7 分钟
数据卷是Docker中用于持久化数据的机制。容器中的数据默认是临时的,容器删除后数据也会丢失。数据卷允许我们将数据存储在主机文件系统或其他容器中,实现数据的持久化。
为什么需要数据卷?¶
容器内的文件系统是临时的,当容器被删除时,其中的所有数据也会丢失。这对于数据库、文件存储等需要持久化的应用来说是不可接受的。数据卷解决了这个问题,它提供了:
- 数据持久化:即使容器删除,数据仍然保留
- 数据共享:多个容器可以共享同一个数据卷
- 性能:直接访问主机文件系统,性能更好
- 备份和迁移:可以轻松备份和迁移数据
数据卷的类型¶
1. 命名卷(Named Volumes)¶
由Docker管理的卷,存储在Docker的存储目录中。
创建命名卷:
查看所有卷:
查看卷详细信息:
使用命名卷:
Bash
$ docker run -d -v mydata:/data --name container1 nginx
$ docker run -d -v mydata:/data --name container2 nginx
# 两个容器共享同一个数据卷
2. 绑定挂载(Bind Mounts)¶
直接挂载主机文件系统上的目录或文件到容器中。
使用绑定挂载:
Bash
# 挂载主机目录到容器
$ docker run -d -v /home/user/data:/data --name web nginx
# 挂载单个文件
$ docker run -d -v /home/user/config.conf:/etc/nginx/conf.d/default.conf nginx
注意
- 主机路径必须是绝对路径
- 如果主机目录不存在,Docker会自动创建
- 如果容器路径已存在,挂载会覆盖原有内容
3. 匿名卷(Anonymous Volumes)¶
在Dockerfile中使用VOLUME指令或运行时使用-v但不指定名称创建的卷。
区别
匿名卷在容器删除后可能被清理,而命名卷会一直保留直到手动删除。
数据卷操作¶
创建卷¶
Bash
# 创建命名卷
$ docker volume create mydata
# 创建带标签的卷
$ docker volume create --label project=myapp mydata
查看卷列表¶
查看卷详细信息¶
输出示例:
JSON
[
{
"CreatedAt": "2023-01-01T00:00:00Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/mydata/_data",
"Name": "mydata",
"Options": {},
"Scope": "local"
}
]
删除卷¶
谨慎操作
docker volume prune会删除所有未被容器使用的卷,请确保数据已备份。
使用数据卷¶
在docker run中使用¶
Bash
# 使用命名卷
$ docker run -d -v mydata:/data --name myapp nginx
# 使用绑定挂载
$ docker run -d -v /host/path:/container/path --name myapp nginx
# 只读挂载
$ docker run -d -v /host/path:/container/path:ro --name myapp nginx
在Dockerfile中定义¶
在Docker Compose中使用¶
YAML
version: '3.8'
services:
web:
image: nginx
volumes:
# 命名卷
- web-data:/var/www/html
# 绑定挂载
- ./config:/etc/nginx/conf.d
# 只读挂载
- ./readonly:/readonly:ro
volumes:
web-data:
数据卷共享¶
使用--volumes-from¶
将一个容器的数据卷共享给另一个容器:
Bash
# 创建数据容器
$ docker run -d --name datacontainer -v /data busybox
# 其他容器使用datacontainer的卷
$ docker run -d --volumes-from datacontainer --name app1 nginx
$ docker run -d --volumes-from datacontainer --name app2 nginx
多个容器共享命名卷¶
Bash
# 创建命名卷
$ docker volume create shared-data
# 多个容器使用同一个卷
$ docker run -d -v shared-data:/data --name container1 nginx
$ docker run -d -v shared-data:/data --name container2 nginx
实战案例¶
案例1:MySQL数据持久化¶
Bash
# 创建MySQL数据卷
$ docker volume create mysql-data
# 运行MySQL并挂载数据卷
$ docker run -d \
--name mysql \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=mypassword \
mysql:8.0
# 即使删除容器,数据仍然保留
$ docker rm mysql
$ docker run -d \
--name mysql \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=mypassword \
mysql:8.0
# 数据完全恢复
案例2:开发环境代码挂载¶
Bash
# 在开发时挂载代码目录
$ docker run -d \
--name dev-app \
-v $(pwd)/src:/app/src \
-p 5000:5000 \
myapp
# 修改代码后,容器内立即生效(需要应用支持热重载)
案例3:配置文件管理¶
Bash
# 挂载配置文件
$ docker run -d \
--name web \
-v /host/config/nginx.conf:/etc/nginx/nginx.conf:ro \
-p 80:80 \
nginx
数据备份和恢复¶
备份数据卷¶
Bash
# 备份命名卷
$ docker run --rm \
-v mydata:/data \
-v $(pwd):/backup \
alpine tar czf /backup/backup.tar.gz -C /data .
# 备份MySQL数据
$ docker run --rm \
-v mysql-data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/mysql-backup.tar.gz -C /data .
恢复数据卷¶
Bash
# 恢复命名卷
$ docker run --rm \
-v mydata:/data \
-v $(pwd):/backup \
alpine sh -c "cd /data && tar xzf /backup/backup.tar.gz"
最佳实践¶
- 使用命名卷存储数据:对于需要持久化的应用数据,使用命名卷而不是绑定挂载
- 使用绑定挂载存储配置:配置文件通常使用绑定挂载,方便修改
- 设置只读挂载:对于不需要修改的目录,使用只读挂载提高安全性
- 定期备份:建立定期备份数据卷的机制
- 清理未使用的卷:定期清理不再使用的数据卷,释放存储空间
常见问题¶
Q: 容器删除后数据卷还在吗?¶
A: 命名卷会一直保留,直到手动删除。匿名卷在容器删除后可能会被清理。
Q: 如何查看数据卷的实际存储位置?¶
A: 使用docker volume inspect <volume_name>查看Mountpoint字段。
Q: 可以在Dockerfile中指定主机路径吗?¶
A: 不可以。Dockerfile中的VOLUME只能指定容器路径,这是为了可移植性。主机路径只能在运行时通过-v参数指定。
Q: 如何迁移数据卷?¶
A: 可以使用备份和恢复的方法,或者直接复制Docker管理的卷目录。
总结¶
数据卷是Docker中实现数据持久化的关键机制。通过合理使用数据卷,你可以:
- ✅ 实现数据持久化
- ✅ 在容器间共享数据
- ✅ 方便地备份和迁移数据
- ✅ 提高应用性能
掌握数据卷的使用后,你就可以放心地使用Docker部署需要持久化数据的应用了!