【问题标题】:How should I backup & restore docker named volumes我应该如何备份和恢复 docker 命名卷
【发布时间】:2016-07-11 03:16:00
【问题描述】:

我对 docker compose 文件中命名卷的功能有点困惑,特别是在备份/恢复我的应用程序时。

我实际上正在测试这个 dockercompose 文件:

      version: '2'
      services:
          django:
              build: 
                  context: "{{ build_dir }}/docker/django"
              depends_on:
                  - db
              environment:
                  [...]
              volumes:
                  - code:/data/code
                  - www:/var/www
                  - conf:/data/conf
              networks:
                  - front
                  - db
              expose:
                  - "8080"
              entrypoint: "/init"
          db:
              build:
                  context: "{{ build_dir }}/docker/postgres" 
              environment:
                  [...]
              volumes:
                  - data:/var/lib/postgresql/data
              networks:
                  - db

      volumes:
          data:
          www:
          code:
          conf:

      networks:
          front:
              external:
                  name: "proxy_nw"

正如文档所述,我尝试使用命名卷而不是仅数据容器。但是我应该如何备份我的数据?

如果使用仅数据容器,我会做一个docker run --rm --volume-from DOC backup_container save,这真的很容易。

现在我读到in this topic 我应该使用类似docker run --rm --volume data --volume www --volume code --volume conf backup_container save 的东西。这并不是那么简单,因为我有许多具有不同类型和卷名称的应用程序,因此这意味着我保存数据的命令对于每个应用程序都必须不同。它使自动化过程复杂化。

编辑:其实这个语法 docker run --volume data --volume www container_image my_command 不正确。 它需要容器内的挂载点,所以它会是 docker run --volume data:/somewhere --volume www:/somewhereelse container_image my_command。 因此,与备份容器一起使用会更加复杂。

那么,在这种情况下,最佳做法是什么? 我应该为所有容器只使用一个命名卷吗?

【问题讨论】:

  • 实际上将所有内容安装在同一卷中是没有意义的,因为卷中的所有内容都会被弄乱(昨天很晚)。

标签: backup docker-compose


【解决方案1】:

其实应该和官方文档中写的一样。数据卷容器将其数据存储在“虚拟根目录”中,因此您应该使用下一条命令进行备份:

docker run --rm \ 
  --volume [DOCKER_COMPOSE_PREFIX]_[VOLUME_NAME]:/[TEMPORARY_DIRECTORY_TO_STORE_VOLUME_DATA] \
  --volume $(pwd):/[TEMPORARY_DIRECTORY_TO_STORE_BACKUP_FILE] \
  ubuntu \
  tar cvf /[TEMPORARY_DIRECTORY_TO_STORE_BACKUP_FILE]/[BACKUP_FILENAME].tar /[TEMPORARY_DIRECTORY_TO_STORE_VOLUME_DATA]

地点:

  • --rm 表示为这个运行命令创建的镜像会被清理
  • DOCKER_COMPOSE_PREFIX 默认是您的项目目录名称
  • VOLUME_NAME 是撰写文件中的数据卷容器名称
  • TEMPORARY_DIRECTORY_TO_STORE_VOLUME_DATA是挂载卷数据的目录
  • TEMPORARY_DIRECTORY_TO_STORE_BACKUP_FILE 是一个虚拟映射到您当前目录的目录,备份将放置在该目录中
  • BACKUP_FILENAME - 备份文件的名称(您可以在当前目录中找到它)
  • ubuntu - 您可以使用 tar 将图像类型更改为另一个容器 :)

将数据取回卷中(恢复):

docker run --rm \ 
  --volume [DOCKER_COMPOSE_PREFIX]_[VOLUME_NAME]:/[TEMPORARY_DIRECTORY_STORING_EXTRACTED_BACKUP] \
  --volume $(pwd):/[TEMPORARY_DIRECTORY_TO_STORE_BACKUP_FILE] \
  ubuntu \
  tar xvf /[TEMPORARY_DIRECTORY_TO_STORE_BACKUP_FILE]/[BACKUP_FILENAME].tar -C /[TEMPORARY_DIRECTORY_STORING_EXTRACTED_BACKUP] --strip 1

地点:

  • TEMPORARY_DIRECTORY_STORING_EXTRACTED_BACKUP 是将提取的文件复制到的目录(它与卷链接,因此将写入卷)
  • -C - 告诉 tar 从哪里提取内容
  • --strip 1 - 删除前导路径元素(例如,如果备份内容位于 /temp 文件夹或类似文件夹中,则为父目录)

【讨论】:

  • 由于某种原因,它已从官方文档中删除,知道为什么吗?
  • 这是我找到的最佳解决方案,但重要的是要知道,如果在容器内使用自定义(非 root)用户,访问数据的权限可能会因容器而异。小心这个。
  • @AFP_555 我发现如果我使用 ~--strip 1~ 那么权限就会混乱。但是,您会如何考虑直接解压缩到父目录。在这种情况下,权限是正确的。在上述情况下,更改所有者等的最佳做法是什么?
  • @spacegoing 我从来没有找到解决这类问题的优雅方法:(
  • 是否可以用这个创建一个 docker-compose 一个服务,也可以让一个 cron 来执行这个命令?
【解决方案2】:

基于this answer。 我在这里做了一个简单的工具: docker_named_volume_backup

首先运行命令docker volume ls 列出您要备份的命名卷。

然后进行备份

#sudo backup_docker_volume.sh <volumn_name> <tar_file>
sudo bash ./backup_docker_volume.sh codimd_database-data backup1.tar

恢复

#sudo restore_docker_volume.sh <volumn_name> <tar_file>
sudo bash ./restore_docker_volume.sh codimd_database-data backup1.tar

【讨论】:

    【解决方案3】:

    这是我如何将 mongo 卷数据备份和恢复为 docker 映像的示例。

    # let a9c25f42ccca be mongo container id    
    docker stop a9c25f42ccca
    
    # create a temp container with volume taken from mongo 
    # make a local tar archive inside it
    docker run --name temp_backup --volumes-from a9c25f42ccca ubuntu tar cvf /mongo_backup.tar /data/db
    
    docker start a9c25f42ccca
    
    # make an image and remove temp container
    docker commit temp_backup my_mongo_backup
    docker rm temp_backup
    
    # push image with backup to remote registry if needed
    docker push my_mongo_backup
    

    并恢复。

    #pull image if needed
    docker pull my_mongo_backup
    
    docker stop a9c25f42ccca
    
    # run transient container out from image with backup
    # take volume from mongo
    # clear any existing data
    # restore data from tar arhcive
    docker run --rm --volumes-from a9c25f42ccca my_mongo_backup bash -c "rm -rf /data/db/* && tar xvf /mongo_backup.tar -C /data --strip 1"
    
    docker start a9c25f42ccca
    

    【讨论】:

      【解决方案4】:

      我终于改变了我的方法。我解析容器的卷以查找挂载点,并将所有内容备份在 tar 中的单独文件夹中。

      所以我不是使用容器来执行此操作,而是使用外部脚本。我不知道这是否是一种更好的方法,但效果很好。

      【讨论】:

      • 你可以分享你的脚本
      • @BoKKeR 这个脚本真的与我的特殊需求息息相关。同样在我发帖后的过去 5 年里,情况发生了很大变化,我很长时间没有使用该脚本(迁移到 Kubernetes)
      猜你喜欢
      • 2019-05-06
      • 2023-01-10
      • 1970-01-01
      • 2019-06-27
      • 2015-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多