在 Docker 中,数据卷是实现数据持久化存储的核心机制。它允许将容器内的数据独立于容器生命周期之外进行存储,即使容器被删除,数据依然保留。

以下是实现 Docker 数据卷持久化存储的几种主要方式及其详细操作:


1. Docker 数据卷的三种主要方式

A. 管理卷(Managed Volumes / Docker Volumes)—— 推荐方式

这是 Docker 官方推荐的方式,由 Docker 完全管理。

  • 特点
    • 由 Docker 在宿主机的特定目录(通常是 /var/lib/docker/volumes/)下创建和管理。
    • 与宿主机文件系统解耦,不依赖宿主机的目录结构。
    • 支持卷驱动,可以轻松对接第三方存储(如 NFS、云存储)。
    • 安全性高,容器无法直接访问宿主机文件系统。
  • 适用场景:生产环境、需要跨容器共享数据、需要对接外部存储。
B. 绑定挂载(Bind Mounts)

将宿主机的任意目录或文件直接挂载到容器中。

  • 特点
    • 直接映射宿主机路径,灵活性高。
    • 性能通常优于管理卷(少了一层抽象)。
    • 依赖宿主机的目录结构,可移植性差。
    • 容器可以访问宿主机文件系统,存在安全风险。
  • 适用场景:开发环境、需要实时编辑代码、配置文件共享。
C. 内存文件系统(tmpfs Mounts)

将数据存储在宿主机的内存中,不写入磁盘。

  • 特点
    • 数据存储在内存中,读写速度极快。
    • 容器停止后数据丢失。
    • 不占用磁盘空间。
  • 适用场景:临时数据、敏感数据(不希望持久化到磁盘)、缓存。

2. 详细操作指南

A. 使用管理卷(Managed Volumes)

1. 创建数据卷

# 创建一个名为 my-data 的数据卷
docker volume create my-data

# 查看所有数据卷
docker volume ls

# 查看数据卷详细信息
docker volume inspect my-data

2. 启动容器并挂载数据卷

# -v 或 --mount 参数挂载数据卷
# 语法:-v <卷名>:<容器内路径>[:权限]
docker run -d \
  --name my-container \
  -v my-data:/app/data \
  nginx:latest

3. 验证数据持久化

# 在容器内创建文件
docker exec my-container touch /app/data/test.txt

# 删除容器
docker rm -f my-container

# 启动新容器并挂载同一数据卷
docker run -d \
  --name new-container \
  -v my-data:/app/data \
  nginx:latest

# 验证文件是否存在
docker exec new-container ls /app/data
# 输出:test.txt

4. 清理数据卷

# 删除未使用的数据卷
docker volume prune

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

B. 使用绑定挂载(Bind Mounts)

1. 创建宿主机目录

# 在宿主机创建目录
mkdir -p /host/data

2. 启动容器并挂载目录

# 语法:-v <宿主机路径>:<容器内路径>[:权限]
docker run -d \
  --name my-container \
  -v /host/data:/app/data \
  nginx:latest

3. 验证数据持久化

# 在宿主机创建文件
echo "Hello from host" > /host/data/host.txt

# 在容器内查看文件
docker exec my-container cat /app/data/host.txt
# 输出:Hello from host

4. 只读挂载

# :ro 表示只读权限
docker run -d \
  --name my-container \
  -v /host/data:/app/data:ro \
  nginx:latest

C. 使用内存文件系统(tmpfs Mounts)
# --tmpfs 参数挂载内存文件系统
docker run -d \
  --name my-container \
  --tmpfs /app/cache \
  nginx:latest

3. Docker Compose 中的数据卷配置

docker-compose.yml 中定义数据卷:

version: '3.8'

services:
  db:
    image: postgres:13
    volumes:
      # 使用命名卷
      - db-data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: example

  app:
    image: my-app:latest
    volumes:
      # 使用绑定挂载
      - ./src:/app/src
      # 使用只读绑定挂载
      - ./config:/app/config:ro
      # 使用内存文件系统
      - type: tmpfs
        target: /app/cache

# 定义命名卷
volumes:
  db-data:
    driver: local

4. 数据卷的高级特性

A. 数据卷驱动

Docker 支持多种卷驱动,可以对接外部存储系统:

# 使用 NFS 驱动创建数据卷
docker volume create \
  --driver local \
  --opt type=nfs \
  --opt o=addr=192.168.1.100,rw \
  --opt device=:/path/to/nfs/share \
  nfs-volume
B. 数据卷容器(Volume Containers)

使用专用容器来管理数据卷,其他容器通过 --volumes-from 继承数据卷:

# 创建数据卷容器
docker create -v /data --name data-container busybox

# 启动应用容器并继承数据卷
docker run -d --volumes-from data-container --name app1 my-app
docker run -d --volumes-from data-container --name app2 my-app
C. 数据卷备份与恢复

备份数据卷

# 启动临时容器挂载数据卷和备份目录
docker run --rm \
  -v my-data:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/backup.tar.gz /data

恢复数据卷

# 启动临时容器解压备份文件到数据卷
docker run --rm \
  -v my-data:/data \
  -v $(pwd):/backup \
  alpine sh -c "cd /data && tar xzf /backup/backup.tar.gz --strip 1"

5. 最佳实践

  1. 生产环境优先使用管理卷:管理卷由 Docker 管理,更安全、更易移植。
  2. 开发环境使用绑定挂载:方便实时编辑代码和配置文件。
  3. 敏感数据使用 tmpfs:避免敏感信息持久化到磁盘。
  4. 定期备份数据卷:使用脚本或工具定期备份重要数据。
  5. 使用 .dockerignore:避免将不必要的文件复制到镜像中。
  6. 设置适当的权限:使用 :ro 只读挂载保护重要数据。

6. 常用命令速查

# 数据卷管理
docker volume create <name>          # 创建数据卷
docker volume ls                      # 列出所有数据卷
docker volume inspect <name>          # 查看数据卷详情
docker volume rm <name>               # 删除数据卷
docker volume prune                   # 删除未使用的数据卷

# 容器挂载
docker run -v <vol>:<path> <image>    # 挂载数据卷
docker run -v <host>:<path> <image>   # 挂载宿主机目录
docker run --tmpfs <path> <image>     # 挂载内存文件系统
docker run --volumes-from <container> <image>  # 继承数据卷

总结

Docker 数据卷是实现数据持久化的关键机制:

  • 管理卷:生产环境首选,安全、易管理、可移植。
  • 绑定挂载:开发环境常用,灵活、高效、依赖宿主机。
  • tmpfs:临时数据、敏感数据、高性能缓存。

合理选择和使用数据卷,可以确保容器化应用的数据安全、持久化和可移植性。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐