Come spostare i contenitori Docker tra diversi host?


98

Non riesco a trovare un modo per spostare la finestra mobile che esegue i container da un host a un altro.

Esiste un modo per inviare i miei contenitori ai repository come facciamo per le immagini? Al momento, non sto utilizzando i volumi di dati per archiviare i dati associati alle applicazioni in esecuzione all'interno dei contenitori. Quindi alcuni dati risiedono all'interno di contenitori, che voglio persistere prima di riprogettare la configurazione.


Dai un'occhiata a flocker github.com/ClusterHQ/flocker
Adrian Mouat

Nota che potresti voler usare salva / carica invece di esportare / importare, poiché salva conserva i metadati e la cronologia.
Burstaholic

Dovrebbe essere un commento alla risposta di @ aholt?
Martin Thompson

docker saveserve per salvare immagini, non contenitori. docs.docker.com/engine/reference/commandline/save
stmllr

Risposte:


57

Non è possibile spostare un contenitore Docker in esecuzione da un host a un altro.

È possibile eseguire il commit delle modifiche nel contenitore su un'immagine con docker commit, spostare l'immagine su un nuovo host e quindi avviare un nuovo contenitore con docker run. Ciò conserverà tutti i dati che la tua applicazione ha creato all'interno del contenitore.

Nb: non conserva i dati archiviati all'interno dei volumi; è necessario spostare manualmente i volumi di dati sul nuovo host.


@larsks Il primo passo non sarebbe fermare il container e poi eseguire il commit?
valentt

@valentt Entrambi è possibile, eseguire il commit e arrestare il container
crollywood

1
Questa risposta non spiega esattamente i comandi che devi usare, il che rende difficile per un noob come me
Paul Kruger

docker-checkpoint potrebbe consentire di spostare un contenitore "in esecuzione" tra host, se entrambi supportano CRIU.
dGRAMOP

2
1. fermare il contenitore docker stop x; 2. eseguire le modifiche apportate docker commit -p x x; 3. salva il contenitore come immagine docker save -o x x; 4. sposta il file x sul nuovo host e nel nuovo host carica la nuova immagine dokcer load -i x(se -vhai avviato il container con l' opzione, dovrai spostare anche questi file sul nuovo host); 5. Esegui questa immagine condocker run (-v is required to mount these files if needed)
Lau Real il

95

In alternativa, se non desideri eseguire il push in un repository:

  1. Esporta il contenitore in un tarball

    docker export <CONTAINER ID> > /home/export.tar
    
  2. Sposta il tuo tarball su una nuova macchina

  3. Importalo di nuovo

    cat /home/export.tar | docker import - some-name:latest
    

8
Inoltre non conserva i dati archiviati all'interno dei volumi.
stmllr

1
Come dovrebbe funzionare? Dopo l'importazione ottengo una nuova immagine, e poi cosa? Basta fare un nuovo comando di esecuzione?
valentt

2
Questo è in realtà un suggerimento davvero pessimo, specialmente per i contenitori che eseguono database. Ho provato questo suggerimento e non ha funzionato. Potrebbe forse funzionare fermando prima il container?
valentt

2
Questo suggerimento era inteso solo come alternativa. Potrebbe funzionare per la tua situazione, potrebbe non funzionare. Per me, in quel momento stavo configurando i contenitori docker di replica del database e, per l'esportazione / importazione, non mi interessava preservare i dati, poiché eseguivo regolarmente backup dei dati del database su un tarball diverso. Per questo, ha funzionato perfettamente.
Aholt

32

Quello che alla fine ha funzionato per me, dopo molti manuali confusi e tutorial confusi, dal momento che Docker è ovviamente al momento della mia scrittura a sbirciare di aspettative gonfiate , è:

  1. Salva l'immagine docker nell'archivio:
    docker save image_name > image_name.tar
  2. copiare su un'altra macchina
  3. su quell'altra macchina docker, esegui docker load nel modo seguente:
    cat image_name.tar | docker load

L'esportazione e l'importazione, come proposto in un'altra risposta, non esporta porte e variabili, che potrebbero essere necessarie per l'esecuzione del contenitore. E potresti finire con cose come "Nessun comando specificato" ecc ... Quando provi a caricarlo su un'altra macchina.

Quindi, la differenza tra salva ed esporta è che il comando salva salva l'intera immagine con cronologia e metadati, mentre il comando export esporta solo la struttura dei file (senza cronologia o metadati).

Inutile dire che, se hai già quelle porte prese sull'hypervisor docker che stai importando, da qualche altro container docker, finirai in conflitto e dovrai riconfigurare le porte esposte.


1
Estremamente utile. Il messaggio "Nessun comando specificato" mi stava facendo impazzire.
Rintoul

Anche il messaggio "Nessun comando specificato" mi stava facendo impazzire. Uso docker commit <container-id> stackstorm-local: 2.9 e docker pull stackstorm-local: 2.9 da un altro host.
Hua Zhang

18

Dalla documentazione di Docker:

docker exportnon esporta il contenuto dei volumi associati al contenitore. Se un volume è montato sopra una directory esistente nel contenitore, docker exportesporterà il contenuto della directory sottostante , non il contenuto del volume. Fare riferimento a Backup, ripristino o migrazione di volumi di dati nella Guida dell'utente per esempi sull'esportazione di dati in un volume.


arresto dell'hq del cluster ... e BTW per migrare il contenitore, il contenitore deve essere eseguito su ZFS / qualsiasi spazio di archiviazione supportato lun
asvignesh

6

Usa questo script: https://github.com/ricardobranco777/docker-volumes.sh

Questo fa conservare i dati dei volumi.

Utilizzo di esempio:

# 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

1
Non ha funzionato per me su AWS Linux (Centos). Alla fine ho adottato l'approccio a bassa tecnologia di utilizzare Docker Inspect per trovare la directory del volume, quindi copiarlo manualmente.
JasonPlutext

@ JasonPlutext Forse qualcosa relativo a SELinux? Hai SELinux abilitato?
Ricardo Branco

1

Ho provato molte soluzioni per questo, e questa è quella che ha funzionato per me:

1.commetti / salva il contenitore in una nuova immagine:

  1. ++ commit del contenitore:
    # docker stop
    # docker commit CONTAINER_NAME
    # docker save --output IMAGE_NAME.tar IMAGE_NAME: TAG


ps: "Il nostro contenitore CONTAINER_NAME ha un volume montato in" / var / home "" (devi ispezionare il tuo contenitore per specificare il percorso del volume: # docker inspect CONTAINER_NAME)

  1. ++ salva il suo volume: useremo un'immagine di Ubuntu per fare la cosa.
    # mkdir backup
    # docker run --rm --volumes-from CONTAINER_NAME -v $ {pwd} / backup: / backup ubuntu bash -c "cd / var / home && tar cvf /backup/volume_backup.tar."

Ora quando guardi $ {pwd} / backup, troverai il nostro volume in formato tar.
Fino ad ora, abbiamo l'immagine del nostro conatainer "IMAGE_NAME.tar" e il suo volume "volume_backup.tar".

Ora puoi ricreare lo stesso vecchio contenitore su un nuovo host.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.