Como mover contêineres Docker entre hosts diferentes?

98

Não consigo encontrar uma maneira de mover contêineres de execução do docker de um host para outro.

Existe alguma maneira de enviar meus contêineres para repositórios como fazemos para imagens? Atualmente, não estou usando volumes de dados para armazenar os dados associados a aplicativos executados dentro de contêineres. Portanto, alguns dados residem dentro de contêineres, que desejo persistir antes de reprojetar a configuração.

Dinesh Reddy
fonte
Dê uma olhada em flocker github.com/ClusterHQ/flocker
Adrian Mouat
Observe que você pode desejar usar salvar / carregar em vez de exportar / importar, pois salvar preserva os metadados e o histórico.
Burstaholic
Isso deveria ser um comentário para a resposta de @aholt?
Martin Thompson
docker saveé para salvar imagens, não contêineres. docs.docker.com/engine/reference/commandline/save
stmllr

Respostas:

57

Você não pode mover um contêiner do docker em execução de um host para outro.

Você pode confirmar as alterações em seu contêiner para uma imagem com docker commit, mover a imagem para um novo host e, em seguida, iniciar um novo contêiner com docker run. Isso preservará todos os dados que seu aplicativo criou dentro do contêiner.

Nb: não preserva os dados armazenados nos volumes; você precisa mover os volumes de dados manualmente para o novo host.

larsks
fonte
@larsks O primeiro passo não seria parar o container e depois fazer o commit?
dia
@valentt Ambos são possíveis, comprometer o contêiner em execução e parado
crollywood de
1
Esta resposta não explica exatamente os comandos que você precisa usar, o que torna isso difícil para um noob como eu
Paul Kruger
docker-checkpoint pode permitir que você mova um contêiner "em execução" entre os hosts, se ambos suportarem CRIU.
dGRAMOP
2
1. pare o recipiente docker stop x; 2. cometer suas alterações docker commit -p x x; 3. salve o container na imagem docker save -o x x; 4. mova o arquivo x para o novo host e no novo host carregue a nova imagem dokcer load -i x(se você iniciou o contêiner com a -vopção, também terá que mover esses arquivos para o novo host); 5. execute esta imagem comdocker run (-v is required to mount these files if needed)
Lau Real
95

Como alternativa, se você não deseja enviar para um repositório:

  1. Exporte o contêiner para um tarball

    docker export <CONTAINER ID> > /home/export.tar
    
  2. Mova seu tarball para uma nova máquina

  3. Importar de volta

    cat /home/export.tar | docker import - some-name:latest
    
Aholt
fonte
8
Também não preserva os dados armazenados nos volumes.
stmllr
1
Como é que isso deveria funcionar? Após a importação, obtenho uma nova imagem, e depois? Basta fazer um novo comando de execução?
dia
2
Esta é realmente uma sugestão muito ruim, especialmente para contêineres que executam banco de dados. Tentei essa sugestão e não funcionou. Poderia funcionar primeiro parando o contêiner?
dia
2
Esta sugestão era apenas uma alternativa. Pode funcionar para a sua situação, ou não. Para mim, eu estava configurando contêineres docker de replicação de banco de dados na época, e para a exportação / importação, não me importei em preservar os dados, pois estava executando backups dos dados do banco de dados regularmente em um tarball diferente. Para isso, funcionou perfeitamente.
aholt
32

O que funcionou para mim, depois de muitos manuais e tutoriais confusos, uma vez que Docker obviamente está no momento da minha escrita com um vislumbre de expectativas infladas , é:

  1. Salve a imagem do docker no arquivo:
    docker save image_name > image_name.tar
  2. copie em outra maquina
  3. nessa outra máquina docker, execute docker load da seguinte maneira:
    cat image_name.tar | docker load

Exportar e importar, conforme proposto em outras respostas, não exporta portas e variáveis, que podem ser necessárias para o funcionamento do seu contêiner. E você pode acabar com coisas como "Nenhum comando especificado" etc ... Quando você tenta carregá-lo em outra máquina.

Portanto, a diferença entre salvar e exportar é que o comando salvar salva a imagem inteira com histórico e metadados, enquanto o comando export exporta apenas a estrutura dos arquivos (sem histórico ou metadados).

Desnecessário dizer é que, se você já tem essas portas tomadas no docker hyper-visor que você está importando, por algum outro docker container, você acabará em conflito e terá que reconfigurar as portas expostas.

Aleksandar Pavić
fonte
1
Extremamente útil. A mensagem "Nenhum comando especificado" estava me deixando louco.
Rintoul
A mensagem "Nenhum comando especificado" também estava me deixando louco. Eu uso docker commit <container-id> stackstorm-local: 2.9 e docker pull stackstorm-local: 2.9 de outro host.
Hua Zhang
18

Da documentação do Docker:

docker exportnão exporta o conteúdo dos volumes associados ao contêiner. Se um volume for montado sobre um diretório existente no contêiner, docker exportexportará o conteúdo do diretório subjacente , não o conteúdo do volume. Consulte Fazer backup, restaurar ou migrar volumes de dados no guia do usuário para exemplos de exportação de dados em um volume.

Antonio De Marinis
fonte
desligamento hq do cluster ... e BTW para migrar o contêiner, o contêiner deve ser executado no ZFS / qualquer armazenamento compatível lun
asvignesh
6

Use este script: https://github.com/ricardobranco777/docker-volumes.sh

Isso faz preservar os dados em volumes.

Exemplo de uso:

# Stop the container   
docker stop $CONTAINER

# Create a new image   
docker commit $CONTAINER $CONTAINER

# Save image
docker save -o $CONTAINER.tar $CONTAINER

# Save the volumes (use ".tar.gz" if you want compression)
docker-volumes.sh $CONTAINER save $CONTAINER-volumes.tar

# Copy image and volumes to another host
scp $CONTAINER.tar $CONTAINER-volumes.tar $USER@$HOST:

# On the other host:
docker load -i $CONTAINER.tar
docker create --name $CONTAINER [<PREVIOUS CONTAINER OPTIONS>] $CONTAINER

# Load the volumes
docker-volumes.sh $CONTAINER load $CONTAINER-volumes.tar

# Start container
docker start $CONTAINER
Ricardo Branco
fonte
1
Não funcionou para mim no AWS Linux (Centos). No final, optei pela abordagem de baixa tecnologia de usar docker inspect para encontrar o diretório de volume e, em seguida, copiei manualmente.
JasonPlutext
@JasonPlutext Talvez algo relacionado ao SELinux? Você tem SELinux habilitado?
Ricardo Branco
1

Tentei muitas soluções para isso, e esta é a que funcionou para mim:

1.commit / salvar contêiner para uma nova imagem:

  1. ++ confirmar o contêiner:
    # docker stop
    # docker commit CONTAINER_NAME
    # docker save --output IMAGE_NAME.tar IMAGE_NAME: TAG


ps: "Nosso contêiner CONTAINER_NAME tem um volume montado em '/ var / home'" (você deve inspecionar seu contêiner para especificar o caminho do volume: # docker inspect CONTAINER_NAME)

  1. ++ salve seu volume: usaremos uma imagem do Ubuntu para fazer a coisa.
    # backup mkdir
    # docker run --rm --volumes-from CONTAINER_NAME -v $ {pwd} / backup: / backup ubuntu bash -c “cd / var / home && tar cvf /backup/volume_backup.tar.”

Agora, ao olhar para $ {pwd} / backup, você encontrará nosso volume no formato tar.
Até agora, temos a imagem do nosso conatainer 'IMAGE_NAME.tar' e seu volume 'volume_backup.tar'.

Agora você pode recriar o mesmo contêiner antigo em um novo host.

Houssam Ezzoukh
fonte