Wie verschiebe ich Docker-Container zwischen verschiedenen Hosts?

98

Ich kann keine Möglichkeit finden, Docker-Container von einem Host auf einen anderen zu verschieben.

Kann ich meine Container auf irgendeine Weise in Repositorys verschieben, wie wir es für Bilder tun? Derzeit verwende ich keine Datenmengen, um die Daten zu speichern, die Anwendungen zugeordnet sind, die in Containern ausgeführt werden. Einige Daten befinden sich also in Containern, die ich beibehalten möchte, bevor ich das Setup neu entwerfe.

Dinesh Reddy
quelle
Werfen Sie einen Blick auf Flocker github.com/ClusterHQ/flocker
Adrian Mouat
Beachten Sie, dass Sie möglicherweise Speichern / Laden anstelle von Exportieren / Importieren verwenden möchten, da beim Speichern Metadaten und Verlauf beibehalten werden.
Burstaholic
Sollte dies ein Kommentar zu @ aholts Antwort sein?
Martin Thompson
docker savedient zum Speichern von Bildern, nicht von Containern. docs.docker.com/engine/reference/commandline/save
stmllr

Antworten:

56

Sie können einen laufenden Docker-Container nicht von einem Host auf einen anderen verschieben.

Sie können die Änderungen in Ihrem Container in ein Image mit übernehmen docker commit, das Image auf einen neuen Host verschieben und dann einen neuen Container mit starten docker run. Dadurch bleiben alle Daten erhalten, die Ihre Anwendung im Container erstellt hat.

Nb: Es werden keine Daten gespeichert, die in Volumes gespeichert sind. Sie müssen Datenmengen manuell auf einen neuen Host verschieben.

Larsks
quelle
@larsks Wäre es nicht der erste Schritt, den Container anzuhalten und dann das Commit durchzuführen?
Valentt
@valentt Beides ist möglich, um laufenden und gestoppten Container zu begehen
Crollywood
1
Diese Antwort erklärt nicht genau die Befehle, die Sie verwenden müssen, was es für einen Neuling wie mich schwierig macht
Paul Kruger
Mit Docker-Checkpoint können Sie einen "laufenden" Container zwischen Hosts verschieben, wenn beide CRIU unterstützen.
dGRAMOP
2
1. den Behälter anhalten docker stop x; 2. Änderungen vornehmen docker commit -p x x; 3. Speichern Sie den Container im Bild docker save -o x x. 4. Verschieben Sie die x-Datei auf den neuen Host und laden Sie auf dem neuen Host das neue Image dokcer load -i x(wenn Sie den Container mit der -vOption gestartet haben, müssen Sie diese Dateien auch auf den neuen Host verschieben). 5. Führen Sie dieses Bild mitdocker run (-v is required to mount these files if needed)
Lau Real
95

Alternativ, wenn Sie nicht in ein Repository pushen möchten:

  1. Exportieren Sie den Container in einen Tarball

    docker export <CONTAINER ID> > /home/export.tar
    
  2. Bewegen Sie Ihren Tarball auf eine neue Maschine

  3. Importieren Sie es zurück

    cat /home/export.tar | docker import - some-name:latest
    
aholt
quelle
8
Bewahrt auch keine Daten auf, die in Volumes gespeichert sind.
stmllr
1
Wie soll das funktionieren? Nach dem Import bekomme ich ein neues Bild und was dann? Einfach einen neuen Ausführungsbefehl ausführen?
Valentt
2
Dies ist eigentlich ein wirklich schlechter Vorschlag, insbesondere für Container, auf denen eine Datenbank ausgeführt wird. Ich habe diesen Vorschlag ausprobiert und es hat nicht funktioniert. Könnte es vielleicht funktionieren, wenn der Container zuerst gestoppt wird?
Valentt
2
Dieser Vorschlag war eigentlich nur für eine Alternative gedacht. Es könnte für Ihre Situation funktionieren, es könnte nicht. Für mich habe ich zu dieser Zeit Docker-Container für die Datenbankreplikation eingerichtet, und für den Export / Import war es nicht wichtig, die Daten zu erhalten, da ich regelmäßig Sicherungen der Datenbankdaten auf einem anderen Tarball ausführte. Dafür hat das perfekt funktioniert.
Aholt
32

Was nach vielen verwirrenden Handbüchern und verwirrenden Tutorials schließlich für mich funktioniert hat, da Docker offensichtlich zum Zeitpunkt meines Schreibens einen Blick auf überhöhte Erwartungen wirft , ist:

  1. Speichern Sie das Docker-Bild im Archiv:
    docker save image_name > image_name.tar
  2. auf einen anderen Computer kopieren
  3. Führen Sie auf diesem anderen Docker-Computer die Docker-Last folgendermaßen aus:
    cat image_name.tar | docker load

Beim Exportieren und Importieren, wie in anderen Antworten vorgeschlagen, werden keine Ports und Variablen exportiert, die möglicherweise für die Ausführung Ihres Containers erforderlich sind. Und Sie könnten Dinge wie "Kein Befehl angegeben" usw. erhalten, wenn Sie versuchen, es auf einen anderen Computer zu laden.

Der Unterschied zwischen Speichern und Exportieren besteht darin, dass der Befehl Speichern das gesamte Bild mit Verlauf und Metadaten speichert, während der Befehl export nur die Dateistruktur exportiert (ohne Verlauf oder Metadaten).

Es ist unnötig zu erwähnen, dass, wenn Sie diese Ports bereits auf dem Docker-Hypervisier, das Sie importieren, von einem anderen Docker-Container übernommen haben, Sie in einen Konflikt geraten und exponierte Ports neu konfigurieren müssen.

Aleksandar Pavić
quelle
1
Sehr hilfreich. Die Meldung "Kein Befehl angegeben" machte mich verrückt.
Rintoul
Die Meldung "Kein Befehl angegeben" machte mich auch verrückt. Ich verwende Docker Commit <Container-ID> Stackstorm-Local: 2.9 und Docker Pull Stackstorm-Local: 2.9 von einem anderen Host.
Hua Zhang
18

Aus der Docker-Dokumentation:

docker exportexportiert nicht den Inhalt von Volumes, die dem Container zugeordnet sind. Wenn ein Volume über einem vorhandenen Verzeichnis im Container bereitgestellt wird, docker exportwird der Inhalt des zugrunde liegenden Verzeichnisses exportiert , nicht der Inhalt des Volumes. Siehe Sichern, Wiederherstellen oder Migrieren Datenmengen in der Bedienungsanleitung Beispiele auf Daten in einem Volumen zu exportieren.

Antonio De Marinis
quelle
Cluster HQ Shutdown ... und BTW, um Container zu migrieren, sollte der Container auf ZFS / jedem unterstützten Speicher Lun
Asvignesh
6

Verwenden Sie dieses Skript: https://github.com/ricardobranco777/docker-volumes.sh

Dies tut Daten in Mengen erhalten.

Anwendungsbeispiel:

# 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
quelle
1
Hat bei AWS Linux (Centos) nicht funktioniert. Am Ende habe ich den Low-Tech-Ansatz gewählt, Docker Inspect zu verwenden, um das Volume-Verzeichnis zu finden, und dieses dann manuell zu kopieren.
JasonPlutext
@JasonPlutext Vielleicht etwas mit SELinux zu tun? Haben Sie SELinux aktiviert?
Ricardo Branco
1

Ich habe viele Lösungen dafür ausprobiert, und diese hat bei mir funktioniert:

1.commit / speichern Container in neuem Image:

  1. ++ Commit des Containers:
    # Docker Stop
    # Docker Commit CONTAINER_NAME
    # Docker speichern - Ausgabe IMAGE_NAME.tar IMAGE_NAME: TAG


ps: "Unser Container CONTAINER_NAME hat ein gemountetes Volume unter '/ var / home'" (Sie müssen Ihren Container überprüfen, um seinen Volume-Pfad anzugeben: # docker inspect CONTAINER_NAME)

  1. ++ Speichern Sie das Volumen: Wir werden ein Ubuntu-Image verwenden, um die Sache zu tun.
    # 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".

Wenn Sie sich nun $ {pwd} / backup ansehen, finden Sie unser Volume im Tar-Format.
Bis jetzt haben wir das Bild 'IMAGE_NAME.tar' unseres Conatainers und dessen Volume 'volume_backup.tar'.

Jetzt können Sie denselben alten Container auf einem neuen Host neu erstellen.

Houssam Ezzoukh
quelle