数据卷基础 #

什么是数据卷? #

数据卷是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数据卷的基础知识:

  • 数据卷的概念和特点
  • 数据卷的基本操作
  • 数据卷的使用方法
  • 数据卷驱动
  • 数据卷的备份与恢复

下一步 #

接下来,让我们学习 绑定挂载,了解如何挂载主机目录到容器。