我应该如何备份和恢复 docker 命名卷



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

我实际上正在测试这个 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

现在我在本主题中读到我应该使用类似 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 .因此,与备份容器一起使用更加复杂。

那么,在这种情况下的最佳实践是什么?

我应该为所有容器只使用一个命名卷吗?
实际上,

它应该与官方文档中编写的方式相同。数据卷容器将其数据存储在"虚拟根目录"中,因此您应该使用以下命令进行备份:

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 表示将清理为此 run 命令创建的映像
  • 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 文件夹或类似文件夹中,则删除父目录)

基于这个答案。我在这里做了一个简单的工具: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

这是我如何将 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

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

所以我不是使用容器来做这件事,而是使用外部脚本。我不知道这是否是一种更好的方法,但它效果很好。

如官方文档中所述,没有开箱即用的单一命令来备份/恢复卷。一个人应该通过将卷安装到某个容器上并以手册给出的某种合适的方式包装内容来自己完成:

docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
对于

存储在卷中的普通文件,这可能就足够了,但对于数据库,最好使用一些转储生成工具。像mongodump/mongorestorepg_dump/pg_restore来处理元数据而不是二进制文件。由于二进制文件备份与某些数据库版本具有更紧密的耦合。

前段时间我遇到了这个问题,并开发了简单的脚本来满足我的需求。但随着我的应用程序和他们的数量的增长,我决定让它变得普遍。最近,我开源了一个我开发的工具,可以选择将备份上传到Google云端硬盘文件夹。

pip install cobra-archiver

备份所有卷。

cobra backup build

要备份除skip-this-one以外的所有卷并将备份放在./backup目录中,可以使用它。

cobra backup build --exclude skip-this-one --backup-dir ./backup

备份并推送到谷歌云端硬盘。

cobra backup build --push 
    --creds /path/to/google-service-acc-key.json 
    --folder-id google-drive-folder-id 
    --exclude skip-this-volume

此外,它可以像这样备份纯文件系统目录

cobra backup build --dir ./backup/me

要查看某些命令的 cli 描述,该行如下所示。

$ cobra backup build --help

除了备份之外,它还可以轻松恢复以前备份的内容。

cobra backup pull --latest --restore 
    --creds /path/to/google-service-acc-key.json 
    --folder-id google-drive-folder-id

也可以自动执行"转储"数据库备份。要实现这一点,可以使用钩子。请参阅github上的详细信息。真实示例可在 e2e 测试源中找到。

最新更新