Docker 数据管理:备份和恢复指南

Docker 数据管理:备份和恢复指南

0x00 引言

在 Docker 环境中,数据管理是一个重要问题。不同的部署方式会导致数据存储在不同的位置,这直接影响了备份和恢复策略。本指南将详细介绍如何根据不同的部署方式和数据存储位置来制定相应的 Docker 数据备份和恢复方案。关于 Docker 中不同的数据存储方式的详细说明,请参阅《Docker 数据管理:卷和绑定挂载指南》[1]

0x01 数据存储方式回顾

在深入讨论备份和恢复之前,让我们先回顾一下 Docker 中的主要数据存储方式:

  1. 容器内存储:数据存储在容器的文件系统中。
  2. 卷(Volumes):Docker 管理的持久化存储,通常位于 /var/lib/docker/volumes/
  3. 绑定挂载(Bind Mounts):将主机上的目录或文件挂载到容器中。

了解这些存储方式对于制定正确的备份策略至关重要。

0x02 常见部署方式及数据存储

0x02 使用 docker run 命令

0x02 无卷挂载

示例命令:

docker run -d --name myapp -p 8080:80 nginx

这种情况下,数据存储在容器内部。容器被删除后,数据将丢失。

备份方法:

docker cp myapp:/{data_path} /{backup_path}

注意:

  • {data_path} 是容器内应用的默认数据存储路径。每个应用都有其特定的默认路径,可以查阅应用的官方文档获取详细信息。
  • {backup_path} 是主机上用于存储备份的目录路径。
  • 如果一个 docker 应用需要持久化数据,开发者一般不会提供无卷/绑定挂载 docker run 命令。

恢复方法:

  1. 创建新容器
  2. 将备份数据复制到新容器:
docker cp /{backup_path} myapp:/{data_path}

0x02 使用卷挂载

示例命令:

docker run -d --name myapp -v myapp_data:/container/data -p 8080:80 nginx

在这种情况下,数据存储在 Docker 管理的卷中。

备份方法:

docker run --rm -v myapp_data:/source -v /{host_backup_path}:/backup busybox tar cvf /backup/backup.tar /source
这个命令的工作原理如下
  • 创建一个临时 Busybox 容器
  • 将需要备份的数据卷(myapp_data)挂载到容器的 /source 目录
  • 将主机上的备份目录挂载到容器的 /backup 目录
  • 使用 tar 命令创建一个包含 /source 目录内容的备份文件,并将其保存在 /backup 目录中

数据流向

Docker 数据卷 → 临时容器的 /source 目录 → tar 文件 → 临时容器的 /backup 目录 → 主机上的 /{host_backup_path}

注意:{host_backup_path} 是主机上用于存储备份的目录路径。

恢复方法:

  1. 创建新的数据卷(如果需要):

    docker volume create new_myapp_data
    
  2. 恢复数据:

    docker run --rm -v new_myapp_data:/target -v /{host_backup_path}:/backup busybox tar xvf /backup/backup.tar -C /target --strip-components=1
    
这个命令的工作原理如下
  • 创建一个临时 Busybox 容器
  • 将新的数据卷挂载到容器的 /target 目录
  • 将包含备份文件的主机目录挂载到容器的 /backup 目录
  • 使用 tar 命令解压备份文件到 /target 目录,--strip-components=1 确保不会创建额外的目录层级

数据流向

主机上的 /{host_backup_path} → 临时容器的 /backup 目录 → tar 文件解压 → 临时容器的 /target 目录 → 新的 Docker 数据卷

0x02 使用绑定挂载

示例命令:

docker run -d --name myapp -v /{host_data_path}:/container/data -p 8080:80 nginx

在这种情况下,数据直接存储在主机文件系统上。

备份方法:直接备份主机上的 /{host_data_path} 目录。

恢复方法:

  1. 创建新容器,使用相同的绑定挂载
  2. 将备份数据复制到主机的 /{host_data_path} 目录

注意:{host_data_path} 是主机上用于存储数据的目录路径。

0x02 使用 Dockerfile

0x02 在 Dockerfile 中定义 VOLUME

Dockerfile 示例:

FROM nginx
...
VOLUME /app/data

这种情况下,Docker 会在主机上创建一个匿名卷。

备份方法:

  1. 找到卷的挂载点:

    docker inspect -f '{{ (index .Mounts 0).Source }}' myapp
    
  2. 备份该目录内容。

恢复方法:

  1. 创建新容器
  2. 使用 docker cp 命令将备份数据复制到新容器的相应目录

0x02 在 Dockerfile 中使用 COPY 或 ADD 命令

Dockerfile 示例:

FROM nginx
...
COPY ./myapp /app

这种情况下,数据会被复制到容器的文件系统中。

备份方法:

docker commit myapp_instance myapp_backup
docker save myapp_backup > myapp_backup.tar

docker commit 命令创建当前容器状态的新镜像。这会捕获容器中的所有更改,包括通过 COPY 或 ADD 命令添加的文件以及运行时的修改。

docker save 命令将镜像保存为一个 tar 文件,可以用于传输或存档。

注意: 这种方法会创建整个容器的完整快照。可能会导致备份文件较大。对于只需要备份特定数据的情况,考虑使用数据卷或绑定挂载可能更合适。

恢复方法:

  1. 加载备份的镜像:
docker load < myapp_backup.tar
  1. 从加载的镜像创建新容器:
docker run -d --name myapp_restored myapp_backup

0x03 使用 docker-compose 管理容器和卷

创建 docker-compose.yml 文件:

version: '3'
services:
  myapp:
    image: nginx
    volumes:
      - myapp_data:/app/data
      - ./config:/app/config
volumes:
  myapp_data:

在这个例子中,我们同时使用了命名卷(myapp_data)和绑定挂载(./config)。关于如何在 docker-compose 中使用卷和绑定挂载的更多信息,请参考卷和绑定挂载指南

备份方法:

对于命名卷:

docker run --rm -v myapp_data:/source -v /{host_backup_path}:/backup busybox tar cvf /backup/volume_backup.tar /source

对于绑定挂载:直接备份主机上的 ./config 目录。

恢复方法:

  1. 停止服务:docker-compose down

  2. 对于命名卷:

    docker run --rm -v myapp_data:/target -v /{host_backup_path}:/backup busybox tar xvf /backup/volume_backup.tar -C /target --strip-components=1
    
  3. 对于绑定挂载:将备份数据复制回 ./config 目录

  4. 启动服务:docker-compose up -d

注意:{host_backup_path} 是主机上用于存储备份的目录路径。

0x04 最佳实践

  1. 使用 docker-compose:它提供了一种简单、可重复的方式来管理多容器应用及其数据卷。

  2. 优先使用命名卷:命名卷比匿名卷更易于管理和备份。

  3. 使用数据卷备份脚本:创建一个 shell 脚本来自动化备份过程。例如:

    #!/bin/bash
    VOLUME_NAME="myapp_data"
    BACKUP_DIR="/{host_backup_path}"
    TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
    
    docker run --rm -v $VOLUME_NAME:/source -v $BACKUP_DIR:/backup \
      busybox tar cvf /backup/${VOLUME_NAME}_${TIMESTAMP}.tar /source
    
  4. 实施定期备份:使用 cron 作业定期运行备份脚本。

  5. 如果容器较多,编排复杂,考虑使用 Docker SwarmKubernetes:k8s,swarm 可以提供更强大的编排和数据管理功能。

0x05 结语

在 Docker 的世界里,没有什么问题是一个好的持久化策略解决不了的。如果有,那就再加一个数据卷!

记住,了解数据的存储位置是制定有效备份策略的关键。通过选择合适的数据管理方式和实施定期备份,可以显著降低数据丢失的风险。毕竟,在数据的海洋中,备份就是你的救生圈!

参考文献

[1] Docker数据管理:卷和绑定挂载指南

128 个赞

感谢分享 :xhs_033:

3 个赞

感谢感谢

5 个赞

感谢分享

前排马克

感谢分享

感谢分享

1 个赞

感谢分享,收藏了。

很详细!

嗯不错,现在用 NFS 挂载数据

mark一下,谢谢热佬

感谢大佬

感谢分享,学习了

感谢教程

#精华神帖添加

感谢分享 :smile:

感谢分享大佬厉害啊

佬,我在操作中遇到了些问题,①备份迁移太缓慢,②代码逻辑好像还有点问题。下面是我的帖子,您方便帮我看下吗?

docker容器迁移(大家随便说,目前在收集灵感的状态) - 开发调优 / 开发调优, Lv2 - LINUX DO

“那就再加一个数据卷”

这个是什么意思?

进我的收藏夹吃灰吧