第13章 数据卷(Volume)详解

在第12章中,我们了解了Docker的存储机制和三种数据管理方式。本章将深入学习数据卷(Volume)的高级用法,这是Docker推荐的数据持久化方案。

13.1 数据卷基础

13.1.1 什么是数据卷

数据卷是Docker管理的特殊目录,完全独立于容器的生命周期。

text 复制代码
数据卷特点:

1. 持久化存储
   容器删除 → 数据卷保留

2. 容器间共享
   容器A ←→ 数据卷 ←→ 容器B

3. 独立管理
   使用docker volume命令集管理

4. 高性能
   绕过UnionFS,直接访问

5. 可备份迁移
   支持多种备份方案

13.1.2 数据卷存储位置

bash 复制代码
# 查看数据卷默认存储路径
docker info | grep "Docker Root Dir"
# Docker Root Dir: /var/lib/docker

# 数据卷实际存储位置
ls -l /var/lib/docker/volumes/

# 输出示例:
# drwx-----x 3 root root 4096 Feb 10 10:00 mysql-data
# drwx-----x 3 root root 4096 Feb 10 10:05 redis-data
# drwx-----x 3 root root 4096 Feb 10 10:10 app-uploads

# 查看具体数据卷内容
ls -la /var/lib/docker/volumes/mysql-data/_data/

13.2 创建和管理数据卷

13.2.1 创建数据卷

bash 复制代码
# 基本创建
docker volume create mydata

# 创建时指定驱动
docker volume create --driver local mydata

# 创建时添加标签
docker volume create \
  --label env=production \
  --label app=mysql \
  --label version=8.0 \
  mysql-prod-data

# 创建时指定选项(取决于驱动)
docker volume create \
  --driver local \
  --opt type=nfs \
  --opt o=addr=192.168.1.10,rw \
  --opt device=:/path/to/share \
  nfs-volume

13.2.2 查看数据卷

bash 复制代码
# 列出所有数据卷
docker volume ls

# 输出示例:
# DRIVER    VOLUME NAME
# local     mysql-data
# local     redis-data
# local     app-uploads

# 过滤数据卷
docker volume ls --filter name=mysql
docker volume ls --filter label=env=production
docker volume ls --filter dangling=true  # 未使用的卷

# 格式化输出
docker volume ls --format "table {{.Name}}\t{{.Driver}}\t{{.Mountpoint}}"

# 显示悬空卷(未被任何容器使用)
docker volume ls -f dangling=true

13.2.3 查看数据卷详情

bash 复制代码
# 查看详细信息
docker volume inspect mydata

# 输出示例:
# [
#     {
#         "CreatedAt": "2024-02-10T10:00:00+08:00",
#         "Driver": "local",
#         "Labels": {
#             "env": "production",
#             "app": "mysql"
#         },
#         "Mountpoint": "/var/lib/docker/volumes/mydata/_data",
#         "Name": "mydata",
#         "Options": {},
#         "Scope": "local"
#     }
# ]

# 提取特定信息
docker volume inspect mydata --format '{{.Mountpoint}}'
docker volume inspect mydata --format '{{.Driver}}'
docker volume inspect mydata --format '{{json .Labels}}' | jq

# 查看数据卷大小
docker system df -v | grep mydata

13.2.4 删除数据卷

bash 复制代码
# 删除单个数据卷
docker volume rm mydata

# 删除多个数据卷
docker volume rm mydata1 mydata2 mydata3

# 删除未使用的数据卷(推荐)
docker volume prune

# 输出:
# WARNING! This will remove all local volumes not used by at least one container.
# Are you sure you want to continue? [y/N] y

# 强制删除(不提示)
docker volume prune -f

# 删除特定条件的卷
docker volume prune --filter "label!=keep"

# 删除所有数据卷(危险!)
docker volume rm $(docker volume ls -q)

13.2.5 数据卷生命周期

bash 复制代码
# 创建卷
docker volume create mydata

# 容器使用卷
docker run -d -v mydata:/data --name app1 nginx

# 查看卷的引用
docker ps -a --filter volume=mydata

# 停止并删除容器
docker stop app1
docker rm app1

# 卷仍然存在
docker volume ls | grep mydata
# mydata

# 清理未使用的卷
docker volume prune

13.3 挂载数据卷到容器

13.3.1 使用 -v 参数

bash 复制代码
# 挂载命名卷
docker run -d -v mydata:/data nginx

# 挂载多个卷
docker run -d \
  -v mysql-data:/var/lib/mysql \
  -v mysql-logs:/var/log/mysql \
  mysql:8.0

# 只读挂载
docker run -d -v mydata:/data:ro nginx

# 创建匿名卷
docker run -d -v /data nginx
# Docker自动创建一个随机名称的卷

13.3.2 使用 --mount 参数(推荐)

bash 复制代码
# 基本挂载
docker run -d \
  --mount source=mydata,target=/data \
  nginx

# 等同于
docker run -d \
  --mount type=volume,source=mydata,target=/data \
  nginx

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

# 如果卷不存在则创建
docker run -d \
  --mount source=newdata,target=/data \
  nginx

# 指定卷驱动和选项
docker run -d \
  --mount type=volume,source=mydata,target=/data,volume-driver=local \
  nginx

13.3.3 -v vs --mount 对比

bash 复制代码
# -v 方式(简洁但不够明确)
docker run -d -v mydata:/data:ro nginx

# --mount 方式(推荐,更清晰)
docker run -d \
  --mount type=volume,source=mydata,target=/data,readonly \
  nginx

# --mount 的优势:
# 1. 更易读(键值对形式)
# 2. 参数验证更严格
# 3. 支持更多选项
# 4. 卷不存在时的行为可控

13.3.4 实战示例

示例1:MySQL数据持久化

bash 复制代码
# 创建数据卷
docker volume create mysql-data
docker volume create mysql-logs

# 运行MySQL
docker run -d \
  --name mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  -e MYSQL_DATABASE=myapp \
  --mount source=mysql-data,target=/var/lib/mysql \
  --mount source=mysql-logs,target=/var/log/mysql \
  -p 3306:3306 \
  mysql:8.0

# 验证数据持久化
docker exec mysql mysql -uroot -psecret -e "CREATE DATABASE test;"

# 删除容器
docker rm -f mysql

# 重新创建容器(使用相同的卷)
docker run -d \
  --name mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  --mount source=mysql-data,target=/var/lib/mysql \
  -p 3306:3306 \
  mysql:8.0

# 数据仍然存在
docker exec mysql mysql -uroot -psecret -e "SHOW DATABASES;"
# 输出包含test数据库

示例2:多容器共享数据

bash 复制代码
# 创建共享卷
docker volume create shared-files

# 容器1:写入数据
docker run -d \
  --name writer \
  --mount source=shared-files,target=/data \
  alpine sh -c "while true; do date >> /data/log.txt; sleep 5; done"

# 容器2:读取数据
docker run -d \
  --name reader \
  --mount source=shared-files,target=/data \
  alpine tail -f /data/log.txt

# 查看容器2的输出
docker logs -f reader

示例3:Web应用文件上传

bash 复制代码
# 创建上传文件卷
docker volume create app-uploads

# 运行应用
docker run -d \
  --name webapp \
  --mount source=app-uploads,target=/app/uploads \
  -p 8080:8080 \
  mywebapp:latest

# 备份上传的文件
docker run --rm \
  --mount source=app-uploads,target=/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/uploads-$(date +%Y%m%d).tar.gz /data

13.4 命名卷 vs 匿名卷

13.4.1 命名卷(Named Volume)

bash 复制代码
# 创建命名卷
docker volume create mydata

# 使用命名卷
docker run -d -v mydata:/data nginx

# 优点:
# ✅ 易于识别和管理
# ✅ 可以预先创建和配置
# ✅ 便于备份和迁移
# ✅ 可以添加标签和元数据

# 查看命名卷
docker volume ls
# DRIVER    VOLUME NAME
# local     mydata

# 推荐使用场景:
# - 生产环境
# - 需要长期保存的数据
# - 需要在多个容器间共享

13.4.2 匿名卷(Anonymous Volume)

bash 复制代码
# 创建匿名卷
docker run -d -v /data nginx

# Docker自动生成卷名
docker volume ls
# DRIVER    VOLUME NAME
# local     a1b2c3d4e5f6...

# 缺点:
# ❌ 难以识别
# ❌ 容易积累无用卷
# ❌ 不便于管理

# 自动删除匿名卷
docker run -d --rm -v /data nginx
# 容器删除时,匿名卷也会删除

# 使用场景:
# - 临时测试
# - 不需要持久化的场景
# - 使用--rm自动清理

13.4.3 对比和选择

特性 命名卷 匿名卷
卷名 自定义名称 随机生成
易识别
管理 简单 困难
清理 手动 可自动(--rm)
共享 容易 困难
备份 方便 需要查找卷名
推荐场景 生产环境 临时测试

最佳实践

bash 复制代码
# ✅ 推荐:使用命名卷
docker run -d -v mysql-data:/var/lib/mysql mysql:8.0

# ❌ 避免:使用匿名卷(除非临时测试)
docker run -d -v /var/lib/mysql mysql:8.0

# ✅ 临时测试:使用匿名卷+自动删除
docker run --rm -v /data alpine sh -c "echo test > /data/file.txt"

13.5 数据卷的备份与恢复

13.5.1 备份数据卷

方法1:使用临时容器备份

bash 复制代码
# 备份数据卷到tar文件
docker run --rm \
  --mount source=mysql-data,target=/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/mysql-data-backup.tar.gz /data

# 或使用ubuntu镜像(如果需要更多工具)
docker run --rm \
  --mount source=mysql-data,target=/data \
  -v $(pwd):/backup \
  ubuntu tar czf /backup/mysql-data-backup.tar.gz -C /data .

方法2:直接复制数据卷目录

bash 复制代码
# 查找数据卷路径
VOLUME_PATH=$(docker volume inspect mysql-data --format '{{.Mountpoint}}')

# 备份
sudo tar czf mysql-data-backup.tar.gz -C $VOLUME_PATH .

# 或复制整个目录
sudo cp -r $VOLUME_PATH ./mysql-data-backup

方法3:使用数据库专用备份工具

bash 复制代码
# MySQL备份
docker exec mysql mysqldump -uroot -psecret --all-databases > backup.sql

# PostgreSQL备份
docker exec postgres pg_dumpall -U postgres > backup.sql

# Redis备份
docker exec redis redis-cli BGSAVE
docker cp redis:/data/dump.rdb ./backup/

13.5.2 恢复数据卷

方法1:从tar文件恢复

bash 复制代码
# 创建新的数据卷
docker volume create mysql-data-restored

# 恢复数据
docker run --rm \
  --mount source=mysql-data-restored,target=/data \
  -v $(pwd):/backup \
  alpine sh -c "cd /data && tar xzf /backup/mysql-data-backup.tar.gz --strip 1"

# 使用恢复的卷启动容器
docker run -d \
  --name mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  --mount source=mysql-data-restored,target=/var/lib/mysql \
  mysql:8.0

方法2:从目录恢复

bash 复制代码
# 创建数据卷
docker volume create mysql-data-new

# 获取卷路径
VOLUME_PATH=$(docker volume inspect mysql-data-new --format '{{.Mountpoint}}')

# 恢复数据
sudo tar xzf backup.tar.gz -C $VOLUME_PATH

# 或直接复制
sudo cp -r ./backup/* $VOLUME_PATH/

方法3:使用数据库恢复命令

bash 复制代码
# MySQL恢复
docker exec -i mysql mysql -uroot -psecret < backup.sql

# PostgreSQL恢复
docker exec -i postgres psql -U postgres < backup.sql

# Redis恢复
docker cp ./dump.rdb redis:/data/
docker restart redis

13.5.3 自动化备份脚本

bash 复制代码
#!/bin/bash
# backup-volumes.sh

BACKUP_DIR="./backups"
DATE=$(date +%Y%m%d-%H%M%S)

# 创建备份目录
mkdir -p $BACKUP_DIR

# 备份函数
backup_volume() {
    local volume_name=$1
    local backup_file="$BACKUP_DIR/${volume_name}-${DATE}.tar.gz"
    
    echo "Backing up volume: $volume_name"
    
    docker run --rm \
        --mount source=$volume_name,target=/data \
        -v $BACKUP_DIR:/backup \
        alpine tar czf /backup/$(basename $backup_file) -C /data .
    
    if [ $? -eq 0 ]; then
        echo "✅ Backup successful: $backup_file"
    else
        echo "❌ Backup failed: $volume_name"
    fi
}

# 备份指定的卷
if [ -n "$1" ]; then
    backup_volume $1
else
    # 备份所有命名卷
    for volume in $(docker volume ls --format "{{.Name}}" | grep -v "^[a-f0-9]\{64\}$"); do
        backup_volume $volume
    done
fi

# 清理旧备份(保留最近7天)
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete

echo "Backup completed: $(date)"

使用备份脚本

bash 复制代码
# 备份单个卷
./backup-volumes.sh mysql-data

# 备份所有卷
./backup-volumes.sh

# 设置定时任务
crontab -e
# 每天凌晨2点备份
0 2 * * * /path/to/backup-volumes.sh

13.5.4 恢复脚本

bash 复制代码
#!/bin/bash
# restore-volume.sh

if [ $# -lt 2 ]; then
    echo "Usage: $0 <backup-file> <volume-name>"
    exit 1
fi

BACKUP_FILE=$1
VOLUME_NAME=$2

# 检查备份文件是否存在
if [ ! -f "$BACKUP_FILE" ]; then
    echo "Error: Backup file not found: $BACKUP_FILE"
    exit 1
fi

# 创建数据卷(如果不存在)
if ! docker volume inspect $VOLUME_NAME > /dev/null 2>&1; then
    echo "Creating volume: $VOLUME_NAME"
    docker volume create $VOLUME_NAME
fi

# 恢复数据
echo "Restoring volume: $VOLUME_NAME from $BACKUP_FILE"

docker run --rm \
    --mount source=$VOLUME_NAME,target=/data \
    -v $(dirname $BACKUP_FILE):/backup \
    alpine sh -c "cd /data && tar xzf /backup/$(basename $BACKUP_FILE)"

if [ $? -eq 0 ]; then
    echo "✅ Restore successful"
else
    echo "❌ Restore failed"
    exit 1
fi

使用恢复脚本

bash 复制代码
# 恢复数据卷
./restore-volume.sh ./backups/mysql-data-20240210-120000.tar.gz mysql-data-new

13.6 数据卷的迁移

13.6.1 同主机迁移

bash 复制代码
# 方法1:重命名卷(实际上是创建新卷并复制数据)
# 备份旧卷
docker run --rm \
  --mount source=old-volume,target=/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/temp.tar.gz /data

# 创建新卷并恢复
docker volume create new-volume
docker run --rm \
  --mount source=new-volume,target=/data \
  -v $(pwd):/backup \
  alpine sh -c "cd /data && tar xzf /backup/temp.tar.gz --strip 1"

# 清理临时文件
rm temp.tar.gz

# 方法2:使用docker cp(适合小数据量)
docker run -d --name temp --mount source=old-volume,target=/data alpine sleep 3600
docker cp temp:/data ./temp-data
docker volume create new-volume
docker run -d --name temp2 --mount source=new-volume,target=/data alpine sleep 3600
docker cp ./temp-data/. temp2:/data
docker rm -f temp temp2
rm -rf ./temp-data

13.6.2 跨主机迁移

bash 复制代码
# 在源主机上
# 1. 备份数据卷
docker run --rm \
  --mount source=mysql-data,target=/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/mysql-data.tar.gz /data

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

# 在目标主机上
# 3. 创建数据卷
docker volume create mysql-data

# 4. 恢复数据
docker run --rm \
  --mount source=mysql-data,target=/data \
  -v /tmp:/backup \
  alpine sh -c "cd /data && tar xzf /backup/mysql-data.tar.gz --strip 1"

# 5. 启动容器
docker run -d \
  --name mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  --mount source=mysql-data,target=/var/lib/mysql \
  mysql:8.0

13.6.3 使用卷插件迁移

bash 复制代码
# 使用NFS卷插件实现跨主机共享
# 在所有主机上安装NFS卷插件
docker plugin install --grant-all-permissions vieux/sshfs

# 创建NFS卷
docker volume create \
  --driver vieux/sshfs \
  -o sshcmd=user@192.168.1.10:/path/to/data \
  -o password=secret \
  nfs-volume

# 在任何主机上使用
docker run -d --mount source=nfs-volume,target=/data nginx

13.7 数据卷驱动程序

13.7.1 本地驱动(local)

bash 复制代码
# 默认驱动
docker volume create mydata

# 显式指定local驱动
docker volume create --driver local mydata

# 使用local驱动的选项
# 1. 挂载NFS
docker volume create \
  --driver local \
  --opt type=nfs \
  --opt o=addr=192.168.1.10,rw \
  --opt device=:/path/to/share \
  nfs-volume

# 2. 挂载CIFS/SMB
docker volume create \
  --driver local \
  --opt type=cifs \
  --opt o=addr=192.168.1.10,username=user,password=pass \
  --opt device=//192.168.1.10/share \
  smb-volume

# 3. 使用tmpfs
docker volume create \
  --driver local \
  --opt type=tmpfs \
  --opt device=tmpfs \
  --opt o=size=1g \
  temp-volume

13.7.2 第三方驱动

bash 复制代码
# 安装卷插件
docker plugin install --grant-all-permissions vieux/sshfs

# 使用插件创建卷
docker volume create \
  --driver vieux/sshfs \
  -o sshcmd=user@host:/path \
  -o password=secret \
  ssh-volume

# 常用第三方驱动:
# - vieux/sshfs: SSH文件系统
# - local-persist: 本地持久化
# - rexray: 支持多种存储后端(AWS EBS, Google Persistent Disk等)
# - convoy: 支持多种存储后端

13.7.3 查看和管理驱动

bash 复制代码
# 查看已安装的插件
docker plugin ls

# 输出示例:
# ID            NAME                  ENABLED
# 1234567890ab  vieux/sshfs:latest    true

# 禁用插件
docker plugin disable vieux/sshfs

# 启用插件
docker plugin enable vieux/sshfs

# 删除插件
docker plugin rm vieux/sshfs

13.8 数据卷最佳实践

13.8.1 命名规范

bash 复制代码
# ✅ 好的命名(描述性强)
docker volume create mysql-prod-8.0-data
docker volume create redis-cache-session-data
docker volume create app-uploads-2024
docker volume create logs-nginx-prod

# ❌ 不好的命名
docker volume create vol1
docker volume create data
docker volume create temp
docker volume create myvolume

13.8.2 标签使用

bash 复制代码
# 创建时添加标签
docker volume create \
  --label env=production \
  --label app=mysql \
  --label team=backend \
  --label backup=daily \
  mysql-prod-data

# 根据标签查找
docker volume ls --filter label=env=production
docker volume ls --filter label=backup=daily

# 根据标签删除(谨慎)
docker volume prune --filter label=env!=production

13.8.3 权限管理

bash 复制代码
# 创建卷后设置权限
docker volume create mydata

# 使用临时容器设置权限
docker run --rm \
  --mount source=mydata,target=/data \
  alpine sh -c "chown -R 1000:1000 /data && chmod -R 755 /data"

# 验证权限
docker run --rm \
  --mount source=mydata,target=/data \
  alpine ls -la /data

13.8.4 定期维护

bash 复制代码
#!/bin/bash
# volume-maintenance.sh

echo "=== Docker Volume Maintenance ==="

# 1. 显示卷使用情况
echo -e "\n1. Volume Usage:"
docker system df -v | grep -A 100 "Local Volumes space usage"

# 2. 查找未使用的卷
echo -e "\n2. Unused Volumes:"
docker volume ls --filter dangling=true

# 3. 查找大体积卷
echo -e "\n3. Large Volumes:"
for vol in $(docker volume ls -q); do
    size=$(docker run --rm -v $vol:/data alpine du -sh /data 2>/dev/null | cut -f1)
    echo "$vol: $size"
done | sort -h -k2

# 4. 检查卷的容器引用
echo -e "\n4. Volume References:"
for vol in $(docker volume ls -q); do
    refs=$(docker ps -a --filter volume=$vol --format "{{.Names}}" | wc -l)
    echo "$vol: $refs containers"
done

# 5. 清理建议
echo -e "\n5. Cleanup Recommendations:"
unused=$(docker volume ls --filter dangling=true -q | wc -l)
echo "Unused volumes: $unused"
echo "Run 'docker volume prune' to clean up"

13.8.5 监控和告警

bash 复制代码
#!/bin/bash
# volume-monitor.sh

# 设置阈值(GB)
THRESHOLD=10

for vol in $(docker volume ls -q); do
    # 获取卷大小
    size_kb=$(docker run --rm -v $vol:/data alpine du -sk /data 2>/dev/null | cut -f1)
    size_gb=$((size_kb / 1024 / 1024))
    
    if [ $size_gb -gt $THRESHOLD ]; then
        echo "⚠️  Warning: Volume $vol is ${size_gb}GB (threshold: ${THRESHOLD}GB)"
        # 发送告警(示例)
        # curl -X POST https://alert.example.com/webhook \
        #   -d "Volume $vol exceeded threshold: ${size_gb}GB"
    fi
done

13.9 实战案例

13.9.1 完整的数据库部署

bash 复制代码
#!/bin/bash
# deploy-database.sh

# 配置
APP_NAME="myapp"
DB_NAME="mysql"
VOLUME_DATA="${APP_NAME}-${DB_NAME}-data"
VOLUME_LOGS="${APP_NAME}-${DB_NAME}-logs"
NETWORK="${APP_NAME}-net"

# 创建网络
docker network create $NETWORK

# 创建数据卷
docker volume create \
  --label app=$APP_NAME \
  --label component=$DB_NAME \
  --label type=data \
  --label backup=daily \
  $VOLUME_DATA

docker volume create \
  --label app=$APP_NAME \
  --label component=$DB_NAME \
  --label type=logs \
  $VOLUME_LOGS

# 运行数据库
docker run -d \
  --name ${APP_NAME}-${DB_NAME} \
  --network $NETWORK \
  --restart unless-stopped \
  -e MYSQL_ROOT_PASSWORD=secret \
  -e MYSQL_DATABASE=$APP_NAME \
  --mount source=$VOLUME_DATA,target=/var/lib/mysql \
  --mount source=$VOLUME_LOGS,target=/var/log/mysql \
  --health-cmd "mysqladmin ping -h localhost" \
  --health-interval 10s \
  mysql:8.0

echo "Database deployed successfully"
echo "Data volume: $VOLUME_DATA"
echo "Logs volume: $VOLUME_LOGS"

13.9.2 开发和生产环境隔离

bash 复制代码
# 开发环境
docker volume create dev-mysql-data
docker run -d \
  --name dev-mysql \
  --mount source=dev-mysql-data,target=/var/lib/mysql \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=dev \
  mysql:8.0

# 生产环境
docker volume create prod-mysql-data
docker run -d \
  --name prod-mysql \
  --mount source=prod-mysql-data,target=/var/lib/mysql \
  -p 3307:3306 \
  -e MYSQL_ROOT_PASSWORD=secure_password \
  mysql:8.0

13.10 小结

通过本章学习,我们深入掌握了数据卷的使用:

数据卷基础

  • 数据卷的特点和优势
  • 存储位置和结构

创建和管理

  • 创建、查看、删除数据卷
  • 使用标签和元数据
  • 生命周期管理

挂载到容器

  • -v 和 --mount 参数
  • 命名卷 vs 匿名卷
  • 实战示例

备份和恢复

  • 三种备份方法
  • 三种恢复方法
  • 自动化脚本

数据迁移

  • 同主机迁移
  • 跨主机迁移
  • 使用卷插件

卷驱动

  • 本地驱动
  • 第三方驱动
  • 驱动管理

最佳实践

  • 命名和标签规范
  • 权限管理
  • 定期维护
  • 监控和告警

数据卷使用决策

text 复制代码
需要数据持久化?
└─ 是 → 生产环境?
    ├─ 是 → 使用命名卷
    │   ├─ 添加标签
    │   ├─ 设置备份策略
    │   └─ 定期维护
    └─ 否 → 开发环境?
        ├─ 是 → 根据需求选择
        │   ├─ 需要主机访问 → Bind Mount
        │   └─ 不需要 → 命名卷
        └─ 否 → 临时测试
            └─ 使用匿名卷 + --rm

下一步

在第14章中,我们将学习绑定挂载(Bind Mount)的详细用法:

  • 目录挂载语法
  • 权限问题处理
  • 开发环境实时同步
  • 挂载单个文件
  • 与Volume的对比

本章思考题

  1. 为什么推荐在生产环境使用命名卷而不是匿名卷?
  2. 如何设计一个完善的数据卷备份策略?
  3. 数据卷的备份和容器的导出(docker export)有什么区别?
  4. 如何在不停止服务的情况下备份数据卷?
  5. 什么场景下应该使用第三方卷驱动?

相关资源

相关推荐
未既2 小时前
docker & docker-compose离线部署步骤
java·docker
浮尘笔记2 小时前
Docker从入门到实践:安装配置、常用命令与开发环境搭建
运维·docker·容器
未既2 小时前
linux以及docker修改文件描述符
linux·运维·docker
程序员一点2 小时前
第9章:软件包管理(DNF 与 RPM)
linux·运维·openeuler
Mr.小海2 小时前
Docker Compose 实战:多容器应用编排从入门到生产落地
运维·docker·容器
何中应2 小时前
Jenkins如何注册为CentOS7的一个服务
linux·运维·jenkins·开发工具
三点水-here2 小时前
基于 Prometheus 生态的 Kubernetes 全栈监控实战指南
云原生·容器·kubernetes·prometheus
Mr.小海2 小时前
Docker 镜像分层机制:从原理到生产环境的深度实践
运维·docker·容器
yttandb2 小时前
linux的基础命令
linux·运维·服务器