Como posso fazer o backup de um contêiner Docker com seus volumes de dados?

Eu tenho usado este tutum de imagem Docker / wordpress para demonstrar um site WordPress. Recentemente descobri que a imagem usa volumes para os dados do MySQL.

Portanto, o problema é o seguinte: se eu quiser fazer backup e restaurar o contêiner, posso tentar confirmar uma imagem e depois excluir o contêiner e criar um novo contêiner a partir da imagem confirmada. Mas se eu fizer isso, o volume será excluído e todos os meus dados serão eliminados.

Deve haver uma maneira simples de fazer backup do meu contêiner mais seus dados de volume, mas não consigo encontrá-lo em lugar algum.

se eu quiser reverter o contêiner, posso tentar confirmar uma imagem e depois excluir o contêiner e criar um novo contêiner a partir da imagem confirmada. Mas se eu fizer isso, o volume será excluído e todos os meus dados desaparecerão

Como explica o guia do usuário do docker, os volumes de dados servem para manter os dados fora de um sistema de arquivos contêiner. Isso também facilita o compartilhamento de dados entre vários contêineres.

Embora o Docker nunca exclua dados em volumes (a menos que você exclua o contêiner associado com o docker rm -v ), os volumes não referenciados por qualquer contêiner docker são chamados de volumes pendentes . Esses volumes pendentes são difíceis de se livrar e de difícil access.

Isso significa que, assim que o último contêiner usando um volume é excluído, o volume de dados fica pendente e seu conteúdo é de difícil access.

Para evitar esses volumes pendentes, o truque é criar um contêiner docker adicional usando o volume de dados que você deseja manter; de modo que sempre haverá pelo menos esse contêiner docker referenciando o volume. Desta forma, você pode excluir o contêiner docker executando o aplicativo wordpress sem perder a facilidade de access ao conteúdo desse volume de dados.

Esses contêineres são chamados contêineres de volume de dados .

Deve haver uma maneira simples de fazer backup do meu contêiner e dos dados do volume, mas não consigo encontrá-lo em lugar algum.

imagens de encaixe de backup

Para fazer backup das imagens do Docker, use o comando docker save que produzirá um arquivo tar que pode ser usado posteriormente para criar uma nova imagem do Docker com o comando docker load .

contêineres de encaixe de backup

Você pode fazer backup de um contêiner docker por diferentes meios

  • confirmando uma nova imagem do Docker com base no estado atual do contêiner do Docker usando o comando de encaixe do Docker
  • exportando o sistema de arquivos do contêiner do Docker como um arquivo tar usando o comando docker export . Mais tarde, você pode criar uma nova imagem do docker a partir desse arquivo tar com o comando docker import .

Esteja ciente de que esses comandos farão backup apenas do sistema de arquivos em camadas do contêiner do Docker. Isso exclui os volumes de dados .

volumes de dados do estivador de backup

Para fazer backup de um volume de dados, você pode executar um novo contêiner usando o volume que deseja fazer backup e executando o comando tar para produzir um archive do conteúdo do volume, conforme descrito no guia do usuário do docker .

Em seu caso particular, o volume de dados é usado para armazenar os dados de um servidor MySQL. Então, se você quer exportar um arquivo tar para este volume, você precisará parar o servidor MySQL primeiro. Para fazer isso, você terá que parar o contêiner wordpress.

backup dos dados do MySQL

Uma outra maneira é conectar-se remotamente ao servidor MySQL para produzir um despejo de database com o comando mysqldump . No entanto, para que isso funcione, seu servidor MySQL deve ser configurado para aceitar conexões remotas e também ter um usuário com permissão para se conectar remotamente. Isso pode não ser o caso com a imagem docker wordpress que você está usando.


Editar

O Docker introduziu recentemente plugins de volume do Docker que permitem delegar o processamento de volumes a plugins implementados pelos fornecedores.

O comando docker run tem um novo comportamento para a opção -v . Agora é possível passar um nome de volume . Os volumes criados dessa maneira são nomeados e fáceis de serem referenciados posteriormente, facilitando os problemas com volumes pendentes .

Editar 2

O Docker introduziu o comando de docker volume prune do docker volume prune para excluir todos os volumes pendentes com facilidade.

ATUALIZAÇÃO 2

Script de backup de volume único bruto:

 #!/bin/bash # This script allows you to backup a single volume from a container # Data in given volume is saved in the current directory in a tar archive. CONTAINER_NAME=$1 VOLUME_NAME=$2 usage() { echo "Usage: $0 [container name] [volume name]" exit 1 } if [ -z $CONTAINER_NAME ] then echo "Error: missing container name parameter." usage fi if [ -z $VOLUME_NAME ] then echo "Error: missing volume name parameter." usage fi sudo docker run -rm --volumes-from $CONTAINER_NAME -v $(pwd):/backup busybox tar cvf /backup/backup.tar $VOLUME_NAME 

Script de restauração de volume único bruto:

 #!/bin/bash # This script allows you to restore a single volume from a container # Data in restored in volume with same backupped path NEW_CONTAINER_NAME=$1 usage() { echo "Usage: $0 [container name]" exit 1 } if [ -z $NEW_CONTAINER_NAME ] then echo "Error: missing container name parameter." usage fi sudo docker run -rm --volumes-from $NEW_CONTAINER_NAME -v $(pwd):/backup busybox tar xvf /backup/backup.tar 

O uso pode ser assim:

 $ volume_backup.sh old_container /srv/www $ sudo docker stop old_container && sudo docker rm old_container $ sudo docker run -d --name new_container myrepo/new_container $ volume_restore.sh new_container 

Suposições são: o arquivo de backup é denominado backup.tar, ele reside no mesmo diretório que o script de backup e restauração, o nome do volume é o mesmo entre os contêineres.

ATUALIZAR

Parece-me que os volumes de backup dos contêineres não são diferentes dos volumes de backup dos contêineres de dados.

Volumes são nada mais que caminhos ligados a um contêiner, então o processo é o mesmo.

Não sei se o backup do docker também funciona para os mesmos volumes de contêiner, mas você pode usar:

 sudo docker run -rm --volumes-from yourcontainer -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data 

e:

 sudo docker run -rm --volumes-from yournewcontainer -v $(pwd):/backup busybox tar xvf /backup/backup.tar 

ATUALIZAÇÃO FINAL

Existe esta ferramenta legal disponível que permite fazer backup e restaurar contêineres de volumes do docker:

https://github.com/discordianfish/docker-backup

se você tiver um contêiner vinculado a alguns volumes de contêineres como este:

 $ docker run --volumes-from=my-data-container --name my-server ... 

você pode fazer backup de todos os volumes como este:

 $ docker-backup store my-server-backup.tar my-server 

e restaurar assim:

 $ docker-backup restore my-server-backup.tar 

Ou você pode seguir o caminho oficial:

Como portar volumes somente de dados de um host para outro?

Se você só precisa fazer o backup dos volumes montados, basta copiar as pastas do seu Dockerhost .

Nota: Se você estiver no Ubuntu , o Dockerhost é sua máquina local. Se você estiver no Mac , o Dockerhost é sua máquina virtual.

No Ubuntu

Você pode encontrar todas as pastas com volumes aqui: /var/lib/docker/volumes/ para que você possa copiá-las e arquivá-las onde quiser.

No MAC

Não é tão fácil quanto no Ubuntu. Você precisa copiar arquivos da VM.

Aqui está um script de como copiar todas as pastas com volumes da máquina virtual (onde o servidor Docker está sendo executado) para sua máquina local. Presumimos que sua VM da máquina do docker seja a padrão .

 docker-machine ssh default sudo cp -v -R /var/lib/docker/volumes/ /home/docker/volumes docker-machine ssh default sudo chmod -R 777 /home/docker/volumes docker-machine scp -R default:/home/docker/volumes ./backup_volumes docker-machine ssh default sudo rm -r /home/docker/volumes 

Ele vai criar uma pasta ./backup_volumes no seu diretório atual e copiar todos os volumes para esta pasta.

Aqui está um script de como copiar todos os volumes salvos de seu diretório local ( ./backup_volumes ) para a máquina Dockerhost

 docker-machine scp -r ./backup_volumes default:/home/docker docker-machine ssh default sudo mv -f /home/docker/backup_volumes /home/docker/volumes docker-machine ssh default sudo chmod -R 777 /home/docker/volumes docker-machine ssh default sudo cp -v -R /home/docker/volumes /var/lib/docker/ docker-machine ssh default sudo rm -r /home/docker/volumes 

Agora você pode verificar se funciona:

 docker volume ls 

Eu sei que isso é antigo, mas percebo que não há uma solução bem documentada para empurrar um contêiner de dados (como backup) para o hub do docker. Acabei de publicar um breve exemplo de como fazê-lo em https://dzone.com/articles/docker-backup-your-data-volumes-to-docker-hub

A seguir, a linha de fundo

O tutorial do docker sugere que você possa fazer backup e restaurar o volume de dados localmente. Vamos usar essa técnica, adicionar mais algumas linhas para que esse backup seja inserido no hub do docker para facilitar a restauração futura em qualquer local que desejarmos. Então vamos começar. Estes são os passos a seguir:

Backup do volume de dados do contêiner de dados denominado data-container-to-backup

 docker run --rm --volumes-from data-container-backup --name tmp-backup -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /folderToBackup 

Expanda esse arquivo tar em um novo contêiner para que possamos confirmá-lo como parte de sua imagem

 docker run -d -v $(pwd):/backup --name data-backup ubuntu /bin/sh -c "cd / && tar xvf /backup/backup.tar" 

Confirme e envie a imagem com uma tag desejada ($ VERSION)

 docker commit data-backup repo/data-backup:$VERSION docker push repo/data-backup:$VERSION 

Finalmente, vamos limpar

 docker rm data-backup docker rmi $(docker images -f "dangling=true" -q) 

Agora temos uma imagem chamada data-backup em nosso repository, que é simplesmente um sistema de arquivos com os arquivos e pastas de backup. Para usar esta imagem (também conhecida como restauração do backup), fazemos o seguinte:

Execute o contêiner de dados com a imagem de backup de dados

 run -v /folderToBackup --entrypoint "bin/sh" --name data-container repo/data-backup:${VERSION} 

Execute sua imagem whatEver com volumes do contador de dados

 docker run --volumes-from=data-container repo/whatEver 

É isso aí.

Fiquei surpreso por não haver documentação para esse trabalho. Espero que alguém ache isso útil. Eu sei que demorei um pouco para pensar sobre isso.

Digamos que o nome do seu volume seja data_volume . Você pode usar os seguintes comandos para fazer backup e restaurar o volume de e para uma imagem do docker chamada data_image :

Para fazer backup:

 docker run --rm --mount source=data_volume,destination=/data alpine tar -c -f- data | docker run -i --name data_container alpine tar -x -f- docker container commit data_container data_image docker rm data_container 

Restaurar:

 docker run --rm data_image tar -c -f- data | docker run -i --rm --mount source=data_volume,destination=/data alpine tar -x -f- 

O comando a seguir executará o tar em um contêiner com todos os volumes de dados nomeados montados e redirectá a saída para um arquivo:

 docker run --rm `docker volume list -q | egrep -v '^.{64}$' | awk '{print "-v " $1 ":/mnt/" $1}'` alpine tar -C /mnt -cj . > data-volumes.tar.bz2 

Certifique-se de testar o arquivo resultante no caso de algo dar errado:

 tar -tjf data-volumes.tar.bz2 

Eu criei uma ferramenta para orquestrar e executar backup de dados e contêineres do mysql, simplesmente chamado de docker-backup . Há até mesmo uma imagem pronta para uso no hub do docker .

É principalmente escrito em Bash, pois é principalmente orquestração. Ele usa duplicity para o mecanismo de backup real. Você pode atualmente fazer backup para FTP (S) e Amazon S3.

A configuração é bem simples: escreva um arquivo de configuração em YAML descrevendo o que fazer backup e onde, e aqui vai você!

Para contêineres de dados, ele monta automaticamente os volumes compartilhados por seu contêiner para fazer backup e processá-lo. Para contêineres mysql, ele os vincula e executa um mysqldump empacotado com seu contêiner e processa o resultado.

Escrevi porque uso o Docker-Cloud, que não está atualizado com as recentes versões do mecanismo do docker e porque eu queria adotar o Docker ao não include nenhum processo de backup nos contêineres do meu aplicativo.

Se você gosta de inserir operadores arcanos a partir da linha de comando, você vai adorar estas técnicas manuais de backup de contêineres. Tenha em mente que há uma maneira mais rápida e eficiente de fazer o backup de contêineres que é tão eficaz quanto. Eu escrevi instruções aqui: https://www.morpheusdata.com/blog/2017-03-02-how-to-create-a-docker-backup-with-morpheus

Etapa 1: adicionar um host do Docker a qualquer nuvem Como explicado em um tutorial no site de suporte do Morpheus, você pode adicionar um host do Docker à nuvem de sua escolha em questão de segundos. Comece escolhendo Infraestrutura na barra de navegação principal do Morpheus. Selecione Hosts na parte superior da janela Infrastructure e clique no botão “+ Container Hosts” no canto superior direito.

Para fazer backup de um host do Docker para uma nuvem via Morpheus, navegue até a canvas Infrastructure e abra o menu “+ Container Hosts”.

Escolha um tipo de host do contêiner no menu, selecione um grupo e insira os dados nos cinco campos: Nome, Descrição, Visibilidade, Selecionar uma Nuvem e Inserir Tags (opcional). Clique em Avançar e, em seguida, configure as opções do host, escolhendo um plano de serviço. Observe que os campos Volume, Memória e Contagem de CPU estarão visíveis somente se o plano selecionado tiver opções personalizadas ativadas.

Aqui é onde você adiciona e dimensiona volumes, define o tamanho da memory e a contagem de CPU e escolhe uma rede. Você também pode configurar o nome de usuário e a senha do sistema operacional, o nome do domínio e o nome do host, que, por padrão, é o nome do contêiner inserido anteriormente. Clique em Avançar e adicione qualquer Fluxo de Trabalho de Automação (opcional). Por fim, revise suas configurações e clique em Concluir para salvá-las.

Etapa 2: Adicionar Integração do Registro do Docker a Nuvens Públicas ou Privadas Adam Hicks descreve em outro tutorial do Morpheus como é simples integrá-lo a um Registro do Docker particular. (Nenhuma configuração adicionada é necessária para usar o Morpheus para fornecer imagens com o hub público do Docker usando a API pública do Docker.)

Selecione Integrações na guia Administrador da barra de navegação principal e, em seguida, escolha o botão “+ Nova Integração” no lado direito da canvas. Na janela Integração exibida, selecione Repositório do Docker no menu suspenso Tipo, insira um nome e adicione o ponto de extremidade da API do registro particular. Forneça um nome de usuário e senha para o registro que você está usando e clique no botão Salvar alterações.

Integre um Docker Registry a uma nuvem privada através da checkbox de diálogo Morpheus “New Integration”.

Para provisionar a integração que você acabou de criar, escolha Docker em Type na checkbox de diálogo Create Instance, selecione o registro no menu suspenso Docker Registry na guia Configure e continue o provisionamento como faria com qualquer contêiner Docker.

Etapa 3: gerenciar backups Depois de adicionar o host do Docker e integrar o registro, um backup será configurado e executado automaticamente para cada instância fornecida. O suporte a Morpheus fornece instruções para visualizar backups, criar um backup de instância e criar um backup de servidor.

Se você só precisa de um backup simples para um arquivo, você pode tentar o meu pequeno utilitário: https://github.com/loomchild/volume-backup

Exemplo

Cópia de segurança:

 docker run -v some_volume:/volume -v /tmp:/backup --rm loomchild/volume-backup backup archive1 

irá arquivar o volume chamado some_volume para o arquivo /tmp/archive1.tar.bz2

Restaurar:

 docker run -v some_volume:/volume -v /tmp:/backup --rm loomchild/volume-backup restore archive1 

irá limpar e restaurar o volume chamado some_volume do arquivo /tmp/archive1.tar.bz2 .

Mais informações: http://loomchild.net/2017/03/26/backup-restore-docker-named-volumes/

Se você tem um caso tão simples quanto o meu, você pode fazer o seguinte:

  1. Crie um Dockerfile que estenda a imagem de base do seu contêiner
  2. Eu suponho que seus volumes são mapeados para o seu sistema de arquivos, então você pode simplesmente adicionar esses arquivos / pastas à sua imagem usando o ADD folder destination
  3. Feito!

Por exemplo, supondo que você tenha os dados dos volumes em seu diretório inicial, por exemplo, em /home/mydata é possível executar o seguinte:

 DOCKERFILE=/home/dockerfile.bk-myimage docker build --rm --no-cache -t $IMAGENAME:$TAG -f $DOCKERFILE /home/pirate 

Onde seu DOCKERFILE aponta para um arquivo como este:

 FROM user/myimage MAINTAINER Danielo Rodríguez Rivero  WORKDIR /opt/data ADD mydata . 

O resto do material é herdado da imagem de base. Agora você pode enviar essa imagem para a nuvem docker e seus usuários terão os dados disponíveis diretamente em seus contêineres