数据卷基础 #
什么是数据卷? #
数据卷是Docker管理的数据存储区域,独立于容器的生命周期存在。它允许容器之间共享数据,并保证数据在容器删除后不会丢失。
数据卷特点 #
| 特点 | 说明 |
|---|---|
| 持久化 | 数据独立于容器生命周期 |
| 共享 | 多个容器可共享同一数据卷 |
| 高效 | 直接写入主机文件系统 |
| 安全 | 可设置访问权限 |
| 可移植 | 易于备份和迁移 |
数据存储方式对比 #
text
┌─────────────────────────────────────────────────────┐
│ 数据存储方式对比 │
├─────────────────────────────────────────────────────┤
│ │
│ 容器层存储: │
│ - 数据随容器删除而丢失 │
│ - 读写性能较低 │
│ - 不适合持久化数据 │
│ │
│ 数据卷(Volume): │
│ - 数据独立于容器 │
│ - Docker管理 │
│ - 推荐的持久化方式 │
│ │
│ 绑定挂载(Bind Mount): │
│ - 挂载主机指定路径 │
│ - 主机管理 │
│ - 适合开发环境 │
│ │
│ tmpfs挂载: │
│ - 存储在内存中 │
│ - 临时数据存储 │
│ - 高性能但非持久化 │
│ │
└─────────────────────────────────────────────────────┘
数据卷操作 #
创建数据卷 #
bash
# 创建数据卷
docker volume create myvolume
# 创建带标签的数据卷
docker volume create --label env=prod myvolume
查看数据卷 #
bash
# 列出所有数据卷
docker volume ls
# 查看数据卷详情
docker volume inspect myvolume
# 格式化输出
docker volume inspect --format '{{.Mountpoint}}' myvolume
docker volume inspect --format '{{.CreatedAt}}' myvolume
删除数据卷 #
bash
# 删除指定数据卷
docker volume rm myvolume
# 删除所有未使用的数据卷
docker volume prune
# 强制删除
docker volume rm -f myvolume
使用数据卷 #
挂载数据卷 #
bash
# 使用-v参数
docker run -d -v myvolume:/app/data nginx
# 使用--mount参数(推荐)
docker run -d --mount source=myvolume,target=/app/data nginx
# 只读挂载
docker run -d -v myvolume:/app/data:ro nginx
docker run -d --mount source=myvolume,target=/app/data,readonly nginx
-v vs --mount #
bash
# -v 简写格式
-v [volume-name]:[container-path]:[options]
# --mount 完整格式
--mount type=volume,source=[volume-name],target=[container-path],[options]
# 示例对比
docker run -v myvolume:/app/data:ro nginx
docker run --mount type=volume,source=myvolume,target=/app/data,readonly nginx
自动创建数据卷 #
bash
# 如果数据卷不存在,Docker会自动创建
docker run -d -v newvolume:/app/data nginx
# 查看自动创建的数据卷
docker volume ls
数据卷驱动 #
内置驱动 #
| 驱动 | 说明 |
|---|---|
| local | 本地存储(默认) |
第三方驱动 #
| 驱动 | 说明 |
|---|---|
| nfs | NFS存储 |
| cifs | SMB/CIFS存储 |
| vSphere | vSphere存储 |
| rexray | 多后端存储 |
使用数据卷驱动 #
bash
# 创建使用特定驱动的数据卷
docker volume create --driver local myvolume
# 使用NFS驱动
docker volume create \
--driver local \
--opt type=nfs \
--opt o=addr=192.168.1.100,rw \
--opt device=:/export/data \
nfs-volume
数据卷应用场景 #
数据库数据持久化 #
bash
# MySQL数据持久化
docker run -d \
--name mysql \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
mysql:8.0
# PostgreSQL数据持久化
docker run -d \
--name postgres \
-v postgres-data:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=postgres \
postgres:15
配置文件管理 #
bash
# 挂载配置文件
docker run -d \
--name nginx \
-v nginx-config:/etc/nginx \
-v nginx-html:/usr/share/nginx/html \
nginx:alpine
日志持久化 #
bash
# 日志持久化
docker run -d \
--name app \
-v app-logs:/var/log/app \
myapp:v1.0
Docker Compose中使用数据卷 #
声明和使用数据卷 #
yaml
version: '3.8'
services:
web:
image: nginx
volumes:
- web-data:/usr/share/nginx/html
- web-logs:/var/log/nginx
db:
image: mysql:8.0
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
volumes:
web-data:
web-logs:
db-data:
配置数据卷选项 #
yaml
version: '3.8'
volumes:
myvolume:
driver: local
driver_opts:
type: none
device: /data/myvolume
o: bind
nfs-volume:
driver: local
driver_opts:
type: nfs
o: addr=192.168.1.100,rw
device: ":/export/data"
数据卷备份与恢复 #
备份数据卷 #
bash
# 使用临时容器备份数据卷
docker run --rm \
-v myvolume:/source:ro \
-v $(pwd)/backup:/backup \
alpine tar czf /backup/myvolume-backup.tar.gz -C /source .
# 备份到标准输出
docker run --rm \
-v myvolume:/source:ro \
alpine tar czf - -C /source . > myvolume-backup.tar.gz
恢复数据卷 #
bash
# 恢复数据卷
docker run --rm \
-v myvolume:/target \
-v $(pwd)/backup:/backup \
alpine sh -c "cd /target && tar xzf /backup/myvolume-backup.tar.gz"
# 从标准输入恢复
cat myvolume-backup.tar.gz | docker run --rm -i \
-v myvolume:/target \
alpine sh -c "cd /target && tar xzf -"
迁移数据卷 #
bash
# 导出数据卷
docker run --rm \
-v source-volume:/source:ro \
-v $(pwd):/backup \
alpine tar czf /backup/volume.tar.gz -C /source .
# 导入到新数据卷
docker volume create target-volume
docker run --rm \
-v target-volume:/target \
-v $(pwd):/backup \
alpine tar xzf /backup/volume.tar.gz -C /target
数据卷最佳实践 #
1. 命名规范 #
bash
# 使用有意义的数据卷名称
docker volume create mysql-data
docker volume create redis-data
docker volume create app-logs
# 避免使用默认的匿名卷
2. 定期备份 #
bash
#!/bin/bash
# backup-volumes.sh
BACKUP_DIR="/backup/volumes"
DATE=$(date +%Y%m%d)
for volume in $(docker volume ls -q); do
echo "Backing up $volume..."
docker run --rm \
-v $volume:/source:ro \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/${volume}-${DATE}.tar.gz -C /source .
done
# 清理30天前的备份
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
3. 监控数据卷使用 #
bash
# 查看数据卷使用情况
docker system df -v
# 查看数据卷大小
docker volume inspect myvolume | grep Mountpoint
sudo du -sh $(docker volume inspect --format '{{.Mountpoint}}' myvolume)
4. 清理未使用的数据卷 #
bash
# 查看未使用的数据卷
docker volume ls -qf dangling=true
# 清理未使用的数据卷
docker volume prune
# 清理时排除特定数据卷
docker volume prune --filter "label!=keep"
小结 #
本节学习了Docker数据卷的基础知识:
- 数据卷的概念和特点
- 数据卷的基本操作
- 数据卷的使用方法
- 数据卷驱动
- 数据卷的备份与恢复
下一步 #
接下来,让我们学习 绑定挂载,了解如何挂载主机目录到容器。