• xico

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

    0x00 引言

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

    0x01 数据存储方式回顾

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

    - 容器内存储:数据存储在容器的文件系统中。

    - 卷(Volumes):Docker 管理的持久化存储,通常位于 /var/lib/docker/volumes/。

    - 绑定挂载(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 命令。

    恢复方法:

    - 创建新容器

    • 将备份数据复制到新容器:```

    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}` 是主机上用于存储备份的目录路径。
    
    恢复方法:
    
    - 创建新的数据卷(如果需要):```
    docker volume create new_myapp_data
    ```- 恢复数据:```
    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} 目录。

    恢复方法:

    - 创建新容器,使用相同的绑定挂载

    - 将备份数据复制到主机的 /{host_data_path} 目录

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

    0x02 使用 Dockerfile

    0x02 在 Dockerfile 中定义 VOLUME

    Dockerfile 示例:```
    FROM nginx
    ...
    VOLUME /app/data
    ```这种情况下,Docker 会在主机上创建一个匿名卷。

    备份方法:

    • 找到卷的挂载点:```

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

    恢复方法:

    - 创建新容器

    - 使用 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 文件,可以用于传输或存档。

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

    恢复方法:

    • 加载备份的镜像:```

    docker load < myapp_backup.tar
    ``- 从加载的镜像创建新容器:``
    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` 目录。

    恢复方法:

    - 停止服务:docker-compose down

    • 对于命名卷:```

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

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

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

    0x04 最佳实践

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

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

    • 使用数据卷备份脚本:创建一个 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
    ``- 实施定期备份:使用 cron` 作业定期运行备份脚本。

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

    0x05 结语

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

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

    参考文献

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

    主楼
  • Mister

    感谢分享

    图片

    #1
  • Single

    感谢感谢

    #2
  • CodeCow

    感谢分享

    #3
  • sanpaoba

    前排马克

    #4
  • PLA81

    感谢分享

    #5
  • zhyoung

    感谢分享

    #6
  • Coker

    感谢分享,收藏了。

    #7
  • Feng

    很详细!

    #8
  • admini-linuxdo

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

    #9
  • GMYXDS

    mark一下,谢谢热佬

    #10
  • 韩老魔

    感谢大佬

    #11
  • ke_mengfei

    感谢分享,学习了

    #12
  • 大帅哥

    感谢教程

    #13
  • Neo-linuxdo

    #精华神帖添加

    #14
  • HalfBit007

    感谢分享 ^-^

    #15
  • CowBoy

    感谢分享大佬厉害啊

    #16
  • 大将军蒙毅

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

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

    #17
  • 󠅕󠅣

    “那就再加一个数据卷”

    这个是什么意思?

    #18
  • Ethan_Hunt

    进我的收藏夹吃灰吧

    #19

发表回复

登录后回复