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

121

Conforme descrito na documentação do Docker em Trabalhando com Volumes, há o conceito dos chamados contêineres somente de dados , que fornecem um volume que pode ser montado em vários outros contêineres, não importa se o contêiner somente de dados está realmente em execução ou não.

Basicamente, isso parece incrível. Mas há uma coisa que não entendo.

Esses volumes (que não mapeiam explicitamente para uma pasta no host por motivos de portabilidade, como afirma a documentação) são criados e gerenciados pelo Docker em alguma pasta interna no host (/var/docker/volumes/… ).

Suponha que eu use esse volume e, em seguida, precise migrá-lo de um host para outro - como faço para transferir o volume? AFAICS tem um ID exclusivo - posso simplesmente copiar o volume e seu contêiner somente de dados de acordo para um novo host? Como faço para descobrir quais arquivos copiar? Ou há algum suporte integrado ao Docker que eu ainda não descobri?

Golo Roden
fonte
12
Você pode exportar o diretório do contêiner de dados: docker run --volumes-from <data container> ubuntu tar -cO <volume path> | gzip -c > volume.tgzIsso não depende de detalhes de implementação dos volumes. E importe os dados com tar na segunda máquina.
Jiri
1
Uau, isso é incrível, obrigado :-)))! Se você escrever este comentário como uma resposta, aceitarei com prazer!
Golo Roden

Respostas:

136

A resposta oficial está disponível na seção "Fazer backup, restaurar ou migrar volumes de dados" :

CÓPIA DE SEGURANÇA:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm: remova o contêiner quando ele sair
  • --volumes-from DATA: anexar aos volumes compartilhados pelo contêiner DATA
  • -v $(pwd):/backup: bind monta o diretório atual no container; para escrever o arquivo tar para
  • busybox: uma imagem pequena e mais simples - boa para manutenção rápida
  • tar cvf /backup/backup.tar /data: cria um arquivo tar descompactado de todos os arquivos no diretório / data

RESTAURAR:

# create a new data container
$ sudo docker create -v /data --name DATA2 busybox true
# untar the backup files into the new container᾿s data volume
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# compare to the original container
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt
tommasop
fonte
3
Por enquanto, é melhor usar docker createpara contêineres somente de dados, para que eles não sejam iniciados. Veja o exemplo no início. documentação: docs.docker.com/userguide/dockervolumes/…
FelikZ
1
Então ... Se eu estou tentando fazer backup de um banco de dados Postgres, o que eu substituir /datacom /var/lib/postgresql/data, correto?
425 nsp
6
A seção "Fazer backup, restaurar ou migrar volumes de dados" parece ter sido removida da documentação do Docker :-(
SteveC
2
@Datz é apenas um comando chamado para criar o contêiner de dados, poderia ser qualquer comando que realmente não faz nada. O contêiner inicia e sai imediatamente, mas é usado para manter os dados.
tommasop
1
@rszalski Se, por algum motivo, você precisar que o contêiner permaneça em execução (digamos, você deseja que docker execele continue ), um comando simples é tail -f /dev/nullque nunca sairá, mas usará recursos mínimos. Quando você não precisar mais dele rodando, docker stop data-containerfará isso por você. Os volumes permanecem para outros recipientes.
Jesse Chisholm
16

Você pode exportar o volume para o tar e transferir para outra máquina. E importe os dados com tar na segunda máquina. Isso não depende de detalhes de implementação dos volumes.

# you can list shared directories of the data container
docker inspect <data container> | grep "/vfs/dir/"

# you can export data container directory to tgz
docker run --cidfile=id.tmp --volumes-from <data container> ubuntu tar -cO <volume path> | gzip -c > volume.tgz

# clean up: remove exited container used for export and temporary file
docker rm `cat id.tmp` && rm -f id.tmp
Jiri
fonte
obrigado pela sua resposta. Como posso mover o contêiner de dados de um host para outro?
Dzung Nguyen de
1
@nXqd O contêiner de dados é criado por docker run -v /data-volume -name datacointainer busybox true- você pode executá-lo em qualquer lugar. Depois de criar o contêiner de dados, você pode importar o arquivo tar conforme explicado na resposta.
Jiri de
Obrigado pela sua resposta. Mas eu encontrei outro problema de que precisamos remover o contêiner zumbi que é usado para fazer backup depois. Uma vez que isso não retorna id. Você tem um jeito bom: D
Dzung Nguyen
@nXqd Claro - você deve usar --cidfile=id.txtcomo parâmetro de execução. O ID do contêiner será armazenado no arquivo id.txt. Eu atualizei a resposta.
Jiri
9
Você pode apenas usar em docker run --rmvez de docker run --cidfile ... ; docker rm.
Felix Rabe
16

Estendendo a resposta oficial dos documentos do Docker e a principal resposta aqui , você pode ter os seguintes aliases em seu .bashrc ou .zshrc

# backup files from a docker volume into /tmp/backup.tar.gz
function docker-volume-backup-compressed() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie tar -czvf /backup/backup.tar.gz "${@:2}"
}
# restore files from /tmp/backup.tar.gz into a docker volume
function docker-volume-restore-compressed() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie tar -xzvf /backup/backup.tar.gz "${@:2}"
  echo "Double checking files..."
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie ls -lh "${@:2}"
}
# backup files from a docker volume into /tmp/backup.tar
function docker-volume-backup() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox tar -cvf /backup/backup.tar "${@:2}"
}
# restore files from /tmp/backup.tar into a docker volume
function docker-volume-restore() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox tar -xvf /backup/backup.tar "${@:2}"
  echo "Double checking files..."
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox ls -lh "${@:2}"
}

Observe que o backup é salvo em /tmp, portanto, você pode mover o arquivo de backup salvo lá entre os hosts docker.

Também há dois pares de aliases de backup / restauração. Um usando compressão e debian: jessie e outro sem compressão, mas com busybox. Favor usar compactação se os arquivos para backup forem grandes.

Luís Bianchin
fonte
3

Adicionarei aqui outra ferramenta recente da IBM que, na verdade, é feita para a migração de volume de um host de contêiner para outro. Este é um projeto atualmente em andamento. Portanto, você pode encontrar uma versão diferente com recursos adicionais no futuro.

Cargo foi desenvolvido para migrar contêineres de um host para outro host junto com seus dados com o mínimo de tempo de inatividade. Cargo usa recursos de federação de dados do sistema de arquivos de união para criar uma visão unificada dos dados (principalmente o sistema de arquivos raiz) nos hosts de origem e destino. Isso permite que o Cargo inicie um contêiner quase imediatamente (em milissegundos) no host de destino conforme os dados do sistema de arquivos raiz de origem são copiados para hosts de destino sob demanda (usando uma partição de cópia na gravação (COW) ) ou preguiçosamente em segundo plano (usando rsync) .

Os pontos importantes são: - um centralizedservidor lida com o processo de migração

O link para o projeto é fornecido aqui:

https://github.com/nadgowdas/cargo
Arif A.
fonte
3

Caso suas máquinas estejam em VPCs diferentes ou você queira copiar de / para a máquina local (como no meu caso), você pode usar o dvsync que criei. É basicamente ngrok combinado com rsyncmais de SSH empacotado em duas imagens pequenas (ambas com cerca de 25 MB). Primeiro, você inicia o dvsync-serverem uma máquina da qual deseja copiar os dados (você precisará do, NGROK_AUTHTOKENque pode ser obtido no painel ngrok ):

$ docker run --rm -e NGROK_AUTHTOKEN="$NGROK_AUTHTOKEN" \
  --mount source=MY_VOLUME,target=/data,readonly \
  quay.io/suda/dvsync-server

Em seguida, você pode iniciar o dvsync-clientna máquina para a qual deseja copiar os arquivos, passando o DVSYNC_TOKENmostrado pelo servidor:

docker run -e DVSYNC_TOKEN="$DVSYNC_TOKEN" \
  --mount source=MY_TARGET_VOLUME,target=/data \
  quay.io/suda/dvsync-client 

Assim que a cópia for concluída, o cliente sairá. Isso funciona com Docker CLI, Compose, Swarm e Kubernetes também.

Suda
fonte