Skip to content

数据卷管理

数据卷(Volume)是 Docker 推荐的数据持久化方式,本节深入介绍数据卷的高级管理技巧。

数据卷的存储位置

Docker 管理的数据卷存储在宿主机的特定位置:

bash
# Linux
/var/lib/docker/volumes/<卷名>/_data

# macOS(Docker Desktop)
/Users/<用户名>/Library/Containers/com.docker.docker/Data/vms/0/data/...

# Windows(WSL 2)
\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\
bash
# 查看卷的实际存储路径
docker volume inspect my-volume --format '{{.Mountpoint}}'
# 输出:/var/lib/docker/volumes/my-volume/_data

数据卷生命周期管理

bash
# 创建数据卷
docker volume create my-data

# 创建时添加标签
docker volume create \
  --label project=myapp \
  --label env=production \
  my-data

# 使用特定驱动(默认 local)
docker volume create \
  --driver local \
  --opt type=nfs \
  --opt o=addr=192.168.1.100,rw \
  --opt device=:/path/on/nfs \
  nfs-volume

# 列出所有数据卷
docker volume ls

# 过滤列出
docker volume ls --filter "label=project=myapp"
docker volume ls --filter "dangling=true"  # 未被使用的卷

# 查看详情
docker volume inspect my-data

# 删除指定卷
docker volume rm my-data

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

# 强制删除(不询问确认)
docker volume prune -f

数据卷挂载详解

命名卷(Named Volume)

bash
# -v 语法
docker run -d \
  --name mysql \
  -v mysql-data:/var/lib/mysql \
  mysql:8.0

# --mount 语法(更明确,推荐)
docker run -d \
  --name mysql \
  --mount type=volume,source=mysql-data,target=/var/lib/mysql \
  mysql:8.0

# 只读挂载
docker run -d \
  --mount type=volume,source=my-data,target=/data,readonly \
  nginx

匿名卷(Anonymous Volume)

bash
# 不指定卷名,Docker 自动生成
docker run -d -v /var/lib/mysql mysql:8.0

# 查看自动生成的卷名
docker volume ls
# DRIVER    VOLUME NAME
# local     a1b2c3d4e5f6...(随机 ID)

注意:匿名卷难以追踪,生产环境推荐使用命名卷。

数据卷的备份与恢复

备份数据卷

bash
# 方法一:使用临时容器备份
docker run --rm \
  -v my-volume:/data \          # 挂载要备份的卷
  -v $(pwd):/backup \            # 挂载备份目录
  alpine \
  tar czf /backup/my-volume-backup.tar.gz -C /data .

# 方法二:带时间戳的备份
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
docker run --rm \
  -v my-volume:/data:ro \
  -v $(pwd):/backup \
  alpine \
  tar czf /backup/my-volume-${TIMESTAMP}.tar.gz -C /data .

echo "Backup saved: my-volume-${TIMESTAMP}.tar.gz"

恢复数据卷

bash
# 创建新卷(或清空已有卷)
docker volume create my-volume-restored

# 从备份恢复
docker run --rm \
  -v my-volume-restored:/data \
  -v $(pwd):/backup \
  alpine \
  tar xzf /backup/my-volume-backup.tar.gz -C /data

# 验证恢复结果
docker run --rm \
  -v my-volume-restored:/data \
  alpine \
  ls -la /data

MySQL 数据库备份示例

bash
# MySQL 数据库备份(使用 mysqldump)
docker exec mysql mysqldump \
  -u root \
  -psecret \
  --all-databases \
  > backup_$(date +%Y%m%d).sql

# 恢复 MySQL 数据库
docker exec -i mysql mysql \
  -u root \
  -psecret \
  < backup_20240101.sql

数据卷在不同主机间迁移

方案一:压缩传输

bash
# 在源主机:导出
docker run --rm \
  -v my-volume:/data:ro \
  alpine tar czf - -C /data . \
  > volume-export.tar.gz

# 传输到目标主机
scp volume-export.tar.gz user@target-host:/tmp/

# 在目标主机:创建卷并导入
docker volume create my-volume
cat /tmp/volume-export.tar.gz | docker run --rm -i \
  -v my-volume:/data \
  alpine tar xzf - -C /data

方案二:通过对象存储

bash
# 备份到 S3(需要 AWS CLI)
docker run --rm \
  -v my-volume:/data:ro \
  -e AWS_ACCESS_KEY_ID=$AWS_KEY \
  -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET \
  amazon/aws-cli \
  s3 cp /data s3://my-bucket/backup/ --recursive

数据卷驱动扩展

NFS 共享卷

bash
# 挂载 NFS 共享存储(多主机共享数据)
docker volume create \
  --driver local \
  --opt type=nfs \
  --opt o=addr=192.168.1.100,nfsvers=4,rw \
  --opt device=:/exports/data \
  nfs-data

docker run -d \
  --name myapp \
  --mount source=nfs-data,target=/data \
  myapp:latest

使用第三方驱动

插件说明适用场景
rexray云存储集成(AWS EBS、GCE PD)云环境
convoyZFS/EBS/NFS 支持混合云
flocker跨主机卷管理集群存储

监控数据卷使用情况

bash
# 查看 Docker 磁盘使用总览
docker system df

# 详细输出(含每个卷的大小)
docker system df -v

# 查看指定卷的大小
du -sh /var/lib/docker/volumes/my-volume/_data

数据卷最佳实践

1. 命名规范

bash
# 推荐:使用有意义的名称
docker volume create prod-mysql-data
docker volume create dev-redis-data

# 不推荐:难以识别
docker volume create volume1

2. 为卷添加标签

bash
docker volume create \
  --label app=myapp \
  --label env=production \
  --label backup=daily \
  myapp-prod-data

3. 定期清理未使用的卷

bash
# 查看未使用的卷
docker volume ls --filter dangling=true

# 清理(生产环境确认后执行)
docker volume prune

4. 备份策略

  • 重要数据卷定期备份(建议至少每天一次)
  • 备份文件存储到与 Docker 主机不同的位置
  • 定期测试恢复流程

总结

数据卷管理的核心要点:

  1. 优先使用命名卷,便于管理和识别
  2. 定期备份重要数据卷
  3. 使用标签方便按项目/环境过滤
  4. 定期清理未使用的匿名卷
  5. 监控磁盘使用,避免磁盘空间耗尽

下一节介绍绑定挂载(Bind Mount)的详细用法。