Jak przenosić kontenery Dockera między różnymi hostami?

98

Nie mogę znaleźć sposobu na przeniesienie platformy Docker obsługującej kontenery z jednego hosta na inny.

Czy istnieje sposób, w jaki mogę przesłać moje kontenery do repozytoriów, tak jak robimy to w przypadku obrazów? Obecnie nie używam woluminów danych do przechowywania danych powiązanych z aplikacjami działającymi w kontenerach. Dlatego niektóre dane znajdują się w kontenerach, które chcę zachować przed przeprojektowaniem konfiguracji.

Dinesh Reddy
źródło
Zajrzyj na flocker github.com/ClusterHQ/flocker
Adrian Mouat
Zauważ, że możesz chcieć użyć zapisz / załaduj zamiast eksportu / importu, ponieważ zapisywanie zachowuje metadane i historię.
Burstaholic
Czy powinien to być komentarz do odpowiedzi @ aholt?
Martin Thompson,
docker savesłuży do zapisywania obrazów, a nie kontenerów. docs.docker.com/engine/reference/commandline/save
stmllr

Odpowiedzi:

57

Nie można przenieść uruchomionego kontenera Dockera z jednego hosta na inny.

Możesz zatwierdzić zmiany w swoim kontenerze do obrazu za pomocą docker commit, przenieść obraz na nowy host, a następnie rozpocząć nowy kontener za pomocą docker run. Pozwoli to zachować wszystkie dane, które aplikacja utworzyła w kontenerze.

Uwaga: nie zachowuje danych przechowywanych w woluminach; musisz ręcznie przenieść woluminy danych na nowy host.

larsks
źródło
@larsks Czy pierwszym krokiem nie byłoby zatrzymanie kontenera, a następnie wykonanie zatwierdzenia?
walentynkowy
@valentt Oba są możliwe, popełnienie uruchomionego i zatrzymanego kontenera
crollywood
1
Ta odpowiedź tak naprawdę nie wyjaśnia dokładnie poleceń, których potrzebujesz, co utrudnia takiemu noobowi jak ja
Paul Kruger
docker-checkpoint może pozwolić na przenoszenie „uruchomionego” kontenera między hostami, jeśli oba obsługują CRIU.
DGRAMOP
2
1. zatrzymać pojemnik docker stop x; 2. dokonywać zmian docker commit -p x x; 3. zapisać kontener do obrazu docker save -o x x; 4. przenieś plik x na nowy host i na nowym hoście załaduj nowy obraz dokcer load -i x(jeśli uruchomiłeś kontener z -vopcją, będziesz musiał również przenieść te pliki na nowy host); 5. Uruchom to zdjęcie zdocker run (-v is required to mount these files if needed)
Lau Real
95

Alternatywnie, jeśli nie chcesz wypychać do repozytorium:

  1. Wyeksportuj kontener do tarballa

    docker export <CONTAINER ID> > /home/export.tar
    
  2. Przenieś archiwum na nową maszynę

  3. Zaimportuj go z powrotem

    cat /home/export.tar | docker import - some-name:latest
    
aholt
źródło
8
Nie zachowuje również danych przechowywanych w woluminach.
stmllr
1
Jak to ma działać? Po imporcie otrzymuję nowy obraz i co dalej? Po prostu wykonaj nowe polecenie uruchomienia?
walentynki
2
W rzeczywistości jest to naprawdę zła sugestia, szczególnie w przypadku kontenerów z bazą danych. Wypróbowałem tę sugestię i nie zadziałała. Czy może to zadziałać najpierw z zatrzymaniem kontenera?
walentynki
2
Ta sugestia była tak naprawdę przeznaczona tylko jako alternatywa. To może działać w twojej sytuacji, może nie. U mnie w tym czasie konfigurowałem kontenery dockera replikacji bazy danych, a do eksportu / importu nie przejmowałem się zachowaniem danych, ponieważ regularnie wykonywałem kopie zapasowe danych bazy danych do innego archiwum. W tym celu działało idealnie.
aholt
32

To, co w końcu zadziałało dla mnie, po wielu zagmatwanych podręcznikach i mylących samouczkach, ponieważ Docker jest oczywiście w momencie, gdy piszę, na pierwszy rzut oka zawyżonych oczekiwań , to:

  1. Zapisz obraz dockera w archiwum:
    docker save image_name > image_name.tar
  2. skopiuj na innym komputerze
  3. na tym innym komputerze docker, uruchom ładowanie dockera w następujący sposób:
    cat image_name.tar | docker load

Eksportowanie i importowanie, zgodnie z propozycją w innych odpowiedziach, nie powoduje eksportu portów i zmiennych, które mogą być wymagane do działania kontenera. I możesz skończyć z takimi rzeczami, jak „Nie określono polecenia” itp. Kiedy spróbujesz załadować go na innym komputerze.

Tak więc różnica między zapisaniem a eksportem polega na tym, że polecenie save zapisuje cały obraz z historią i metadanymi, podczas gdy polecenie eksportu eksportuje tylko strukturę plików (bez historii i metadanych).

Nie trzeba dodawać, że jeśli masz już te porty zajęte przez hiper-visor Dockera, który importujesz, przez jakiś inny kontener Dockera, skończysz w konflikcie i będziesz musiał ponownie skonfigurować ujawnione porty.

Aleksandar Pavić
źródło
1
Niezwykle pomocne. Komunikat „Nie określono polecenia” doprowadzał mnie do szału.
Rintoul,
Komunikat „Nie określono polecenia” również doprowadzał mnie do szału. Używam docker commit <container-id> stackstorm-local: 2.9, i docker pull stackstorm-local: 2.9 z innego hosta.
Hua Zhang
18

Z dokumentacji Dockera:

docker exportnie eksportuje zawartości woluminów powiązanych z kontenerem. Jeśli wolumin jest zamontowany na górze istniejącego katalogu w kontenerze, docker exportwyeksportuje zawartość katalogu źródłowego , a nie zawartość woluminu. Przykłady eksportowania danych do wolumenu można znaleźć w części Tworzenie kopii zapasowych, przywracanie lub migracja woluminów danych w podręczniku użytkownika.

Antonio De Marinis
źródło
zamknięcie hq klastra ... i tak przy okazji migracja kontenera, kontener powinien działać na ZFS / dowolnym obsługiwanym magazynie lun
asvignesh
6

Użyj tego skryptu: https://github.com/ricardobranco777/docker-volumes.sh

To robi zachować dane w tomach.

Przykładowe użycie:

# 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
źródło
1
Nie działa dla mnie na AWS Linux (Centos). Ostatecznie skorzystałem z mało zaawansowanego technicznie podejścia polegającego na użyciu docker inspect w celu znalezienia katalogu woluminu, a następnie ręcznie go skopiowałem.
JasonPlutext
@JasonPlutext Może coś związanego z SELinux? Czy masz włączony SELinux?
Ricardo Branco
Mam to: tar: Usuwanie wiodącego `/ 'z nazw członków
hjahan
@hjahan To typowa wiadomość tar. Nie jest to błąd ani nawet ostrzeżenie.
Ricardo Branco
1

Wypróbowałem wiele rozwiązań, a to działa dla mnie:

1. zatwierdź / zapisz kontener na nowy obraz:

  1. ++ zatwierdzenie kontenera:
    # docker stop
    # docker commit CONTAINER_NAME
    # docker save --output IMAGE_NAME.tar IMAGE_NAME: TAG


ps: „Nasz kontener CONTAINER_NAME ma zamontowany wolumen w '/ var / home'” (musisz sprawdzić swój kontener, aby określić ścieżkę wolumenu: # docker inspect CONTAINER_NAME)

  1. ++ zapisz jego objętość: użyjemy obrazu ubuntu, aby to zrobić.
    # 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.”

Teraz, gdy spojrzysz na $ {pwd} / backup, znajdziesz nasz wolumin w formacie tar.
Do tej pory mamy obraz naszego kontenera „IMAGE_NAME.tar” i jego objętość „volume_backup.tar”.

Teraz możesz odtworzyć ten sam stary kontener na nowym hoście.

Houssam Ezzoukh
źródło