Jak skopiować obrazy Docker z jednego hosta na drugi bez użycia repozytorium

1373

Jak przenieść obraz Dockera z jednego komputera na inny bez korzystania z repozytorium, bez względu na to, czy jest ono prywatne czy publiczne?

Tworzę własny obraz w VirtualBox, a kiedy jest gotowy, staram się wdrożyć na innych komputerach, aby mieć rzeczywiste wykorzystanie.

Ponieważ jest oparty na moim własnym obrazie (takim jak Red Hat Linux), nie można go odtworzyć z pliku Docker. Mój plik dokerów nie jest łatwo przenośny.

Czy mogę użyć prostych poleceń? Lub inne rozwiązanie?

Larry Cai
źródło

Odpowiedzi:

2303

Musisz zapisać obraz Dockera jako plik tar:

docker save -o <path for generated tar file> <image name>

Następnie należy skopiować obraz do nowego systemu regularnych narzędzi transferu plików, takich jak cp, scplub rsync(preferowane dla dużych plików). Następnie będziesz musiał załadować obraz do Dockera:

docker load -i <path to image tar file>

PS: Może być konieczne wykonanie sudowszystkich poleceń.

EDYCJA: Powinieneś dodać nazwę pliku (nie tylko katalog) z opcją -o, na przykład:

docker save -o c:/myfile.tar centos:16
Daiwei
źródło
27
To lepsza odpowiedź na obrazy .
Andy
26
Ponadto lepiej jest użyć go repo:tagjako odwołania do obrazu niż image id. Jeśli użyjesz image id, załadowany obraz nie zachowa znacznika (i będziesz musiał zrobić kolejny krok, aby oznaczyć obraz).
wisbucky
1
Użyłem identyfikatora obrazu zamiast nazwy: tag Teraz siedzę tutaj, załadowałem obraz i mam <none> dla REPOSITORY i TAG. Jaki jest właściwy sposób na przywrócenie nazwy i tagu? @wisbucky
Ulfhetnar
3
Aby oznaczyć, najpierw użyj identyfikatora IMAGE ID docker images, a następnie użyj docker tag DESIREDIMAGEID mycompany/myreponame. Jeśli twój identyfikator obrazu to 591de551d6e4, możesz skrócić identyfikator obrazu:docker tag 59 mycompany/myreponame
Junior
582

Przesyłanie obrazu Docker przez SSH, bzipowanie zawartości w locie:

docker save <image> | bzip2 | \
     ssh user@host 'bunzip2 | docker load'

Dobrym pomysłem jest również umieszczenie pvna środku rury, aby zobaczyć, jak przebiega transfer:

docker save <image> | bzip2 | pv | \
     ssh user@host 'bunzip2 | docker load'

(Więcej na ten temat pv: strona główna , strony man ).

kolypto
źródło
19
Korzystając z docker $(docker-machine config mach1) save <image> | docker $(docker-machine config mach2) loadmaszyny dokującej , możesz kopiować obrazy między maszynami mach1 i mach2 .
matlehmann
5
@manojlds eval $(docker-machine env dev)jest dobry do ogólnej komunikacji z jednym hostem dokera, ale nie do kopiowania między dwoma komputerami, ponieważ dotyczy to dwóch różnych hostów / maszyn dokerów.
matlehmann,
14
zrobić to w odwrotnej kolejności (zdalnie na lokalnie):ssh target_server 'docker save image:latest | bzip2' | pv | bunzip2 | docker load
ThorSummoner
2
Czy można to zrobić, gdy doker wymaga sudo na komputerze docelowym? Próbowałem (bez kompresji) docker save my_img:v1 | ssh -t -t my_user@my_machine sudo docker load. Bez przełącznika „-t” sudo narzeka na sudo: przepraszam, musisz mieć tty, aby uruchomić sudo ; z jednym „-t” jest to ta sama wiadomość, ponieważ ssh mówi, że Pseudo-terminal nie zostanie przydzielony, ponieważ stdin nie jest terminalem. i wreszcie, z dwoma „-t”, otrzymuję zawartość pliku tar (tj. obrazu) na moim terminalu. Jakieś pomysły?
głód
1
@JosefStark Musiałem dodać „Domyślne: <docelowa nazwa użytkownika>! Requtty” podczas edycji pliku sudoers, aby zatrzymać komunikat „Przepraszamy” z sudo. Nie wiem, jaką to robi różnicę, ale umieszczam wszystko po użytkowniku @ hoście w cudzysłowie (więc „[...] | ssh użytkownik @ host 'ładuje dokera bunzip2 | sudo'”).
VirtualWolf,
99

Aby zapisać obraz w dowolnej ścieżce pliku lub udostępnionym miejscu NFS, zobacz następujący przykład.

Uzyskaj identyfikator obrazu, wykonując:

sudo docker images

Załóżmy, że masz obraz o identyfikatorze „dane-macierzy”.

Zapisz obraz z identyfikatorem:

sudo docker save -o /home/matrix/matrix-data.tar matrix-data

Skopiuj obraz ze ścieżki do dowolnego hosta. Teraz zaimportuj do lokalnej instalacji Dockera, używając:

sudo docker load -i <path to copied image file>
Sohan
źródło
34

Najpierw zapisz obraz Dockera w pliku zip:

docker save <docker image name> | gzip > <docker image name>.tar.gz

Następnie załaduj wyeksportowany obraz do Dockera za pomocą poniższego polecenia:

zcat <docker image name>.tar.gz | docker load
Damodaran
źródło
11
Do załadunku docker load < my-image.tar.gzwystarczy. Obraz jest automatycznie dekompresowany dla gzip, bzip2 i xz.
Flux
32

Biegać

docker images

aby zobaczyć listę obrazów na hoście. Załóżmy, że masz obraz o nazwie awesomesauce . W swoim terminalu cddo katalogu , do którego chcesz wyeksportować obraz. Teraz uruchom:

docker save awesomesauce:latest > awesomesauce.tar

Skopiuj plik tar na dysk USB lub cokolwiek, a następnie skopiuj go na nowy komputer hosta.

Teraz z nowego hosta wykonaj:

docker load < awesomesauce.tar

Teraz idź napić się kawy i przeczytaj Hacker News ...

Neil Girardi
źródło
4
Warto tutaj zauważyć, że zadziała to tylko wtedy, gdy składowanie i ładowanie są wykonywane w tym samym systemie operacyjnym. Użyj docker save [image] -o file.tari, docker load -i file.taraby tego uniknąć!
Andreas Forslöw,
docker save [image] -o file.tarwydaje się również
znacznie
19

Do spłaszczonego eksportu systemu plików kontenera użyj;

docker export CONTAINER_ID > my_container.tar

Użyj, cat my_container.tar | docker import -aby zaimportować wspomniany obraz.

Panagiotis Moustafellos
źródło
9
będzie to miało miejsce, cat my_container.tar | docker import - my_container:newjeśli zostanie zaimportowane lokalnie zgodnie z pomocą cmd
Larry Cai
7
Jest to bardziej do tworzenia kopii zapasowej działającego kontenera niż do wdrażania obrazu.
Kousha,
15

Korzystając z maszyny dokującej, możesz kopiować obrazy między maszynami mach1i za mach2pomocą:

docker $(docker-machine config <mach1>) save <image> | docker $(docker-machine config <mach2>) load

I oczywiście możesz również trzymać pvsię środka, aby uzyskać wskaźnik postępu:

docker $(docker-machine config <mach1>) save <image> | pv | docker $(docker-machine config <mach2>) load

Możesz także pominąć jedną z docker-machine configpodpowłok, aby użyć bieżącego domyślnego hosta dokera.

docker save <image> | docker $(docker-machine config <mach>) load

skopiować obraz z bieżącego hosta dokera do mach

lub

docker $(docker-machine config <mach>) save <image> | docker load

skopiować z machbieżącego hosta dokera.

matlehmann
źródło
10

Zakładam, że musisz zapisać, couchdb-cartridgektóry ma identyfikator obrazu 7ebc8510bc2c:

stratos@Dev-PC:~$ docker images
REPOSITORY                             TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
couchdb-cartridge                      latest              7ebc8510bc2c        17 hours ago        1.102 GB
192.168.57.30:5042/couchdb-cartridge   latest              7ebc8510bc2c        17 hours ago        1.102 GB
ubuntu                                 14.04               53bf7a53e890        3 days ago          221.3 MB

Zapisz obraz archiveName w pliku tar. Użyję /media/sf_docker_vm/do zapisania obrazu.

stratos@Dev-PC:~$ docker save imageID > /media/sf_docker_vm/archiveName.tar

Skopiuj plik archiveName.tar do nowej instancji Docker użyciu dowolnej metody prace w środowisku, na przykład FTP, SCPitd

Uruchom docker loadpolecenie na nowej instancji Docker i określ lokalizację pliku tar obrazu.

stratos@Dev-PC:~$ docker load < /media/sf_docker_vm/archiveName.tar

Na koniec uruchom docker imagespolecenie, aby sprawdzić, czy obraz jest teraz dostępny.

stratos@Dev-PC:~$ docker images
REPOSITORY                             TAG        IMAGE ID         CREATED             VIRTUAL SIZE
couchdb-cartridge                      latest     7ebc8510bc2c     17 hours ago        1.102 GB
192.168.57.30:5042/couchdb-cartridge   latest     bc8510bc2c       17 hours ago        1.102 GB
ubuntu                                 14.04      4d2eab1c0b9a     3 days ago          221.3 MB

Proszę znaleźć ten szczegółowy post .

tk_
źródło
10

Aby przenieść obrazy z lokalnej instalacji Docker na maszynę wirtualną minikube:

docker save <image> | (eval $(minikube docker-env) && docker load)
Bryan Larsen
źródło
10

docker-push-ssh to narzędzie wiersza polecenia, które utworzyłem właśnie na ten scenariusz.

Tworzy tymczasowy prywatny rejestr Docker na serwerze, ustanawia tunel SSH z lokalnego hosta, wypycha obraz, a następnie czyści po sobie.

Zaletą tego podejścia docker save(podczas pisania większości odpowiedzi przy użyciu tej metody) jest to, że tylko nowe warstwy są wypychane na serwer, co powoduje DUŻO szybsze przesyłanie.

Często używanie rejestru pośredniego, takiego jak dockerhub, jest niepożądane i uciążliwe.

https://github.com/brthor/docker-push-ssh

Zainstalować:

pip install docker-push-ssh

Przykład:

docker-push-ssh -i ~/my_ssh_key [email protected] my-docker-image

Największym zastrzeżeniem jest to, że musisz ręcznie dodać lokalnego hosta do insecure_registrieskonfiguracji Dockera . Uruchom narzędzie raz, a wyświetli się błąd informacyjny:

Error Pushing Image: Ensure localhost:5000 is added to your insecure registries.
More Details (OS X): /programming/32808215/where-to-set-the-insecure-registry-flag-on-mac-os

Gdzie powinienem ustawić flagę „--insecure-register” w systemie Mac OS?

brthornbury
źródło
1
Zredagowałem twoją odpowiedź, aby wyjaśnić, że narzędzie, które polecasz, zostało stworzone przez ciebie. Zobacz tę stronę , w szczególności: „Publikuj dobre, trafne odpowiedzi, a jeśli niektóre (ale nie wszystkie) dotyczą twojego produktu lub strony internetowej, to jest w porządku. Musisz jednak ujawnić swoje powiązanie w swoich odpowiedziach”.
Louis
8

Wszystkie pozostałe odpowiedzi są bardzo pomocne. Właśnie przeszedłem przez ten sam problem i wymyśliłem prosty sposób docker machine scp.

Od czasu Docker Machine v0.3.0 wprowadzono scp do kopiowania plików z jednego komputera Docker na inny. Jest to bardzo wygodne, jeśli chcesz skopiować plik z komputera lokalnego na zdalną maszynę Docker, taką jak AWS EC2 lub Digital Ocean, ponieważ Docker Machine dba o poświadczenia SSH.

  1. Zapisz swoje zdjęcia za pomocą docker save:

    docker save -o docker-images.tar app-web
    
  2. Skopiuj obrazy za pomocą narzędzia docker-machine scp

    docker-machine scp ./docker-images.tar remote-machine:/home/ubuntu
    

Załóżmy, że twój zdalny komputer Docker to remote-machinei katalog, w którym ma znajdować się plik tar /home/ubuntu.

  1. Załaduj obraz Dockera

    docker-machine ssh remote-machine sudo docker load -i docker-images.tar
    
Peng
źródło
5
dlaczego nie tylko „scp <source> <remote>”?
Tamas Kalman
3

Chcę przenieść wszystkie obrazy z tagami.

```
OUT=$(docker images --format '{{.Repository}}:{{.Tag}}')
OUTPUT=($OUT)
docker save $(echo "${OUTPUT[*]}") -o /dir/images.tar
``` 

Wyjaśnienie:

Najpierw OUTpobiera wszystkie tagi, ale oddziela je nowymi wierszami. Drugi OUTPUTpobiera wszystkie tagi w tablicy. Trzeci $(echo "${OUTPUT[*]}")umieszcza wszystkie tagi dla jednego docker savepolecenia, dzięki czemu wszystkie obrazy są w jednym pliku tar.

Dodatkowo można to skompresować za pomocą gzip. Na cel uruchom:

tar xvf images.tar.gz -O | docker load

-Oopcja tarumieszczania zawartości na standardowym interfejsie, którą można pobrać docker load.

Vikram
źródło
2

Możesz użyć sshfs:

$ sshfs user@ip:/<remote-path> <local-mount-path>
$ docker save <image-id> > <local-mount-path>/myImage.tar
Chu
źródło
1

Skrypt do wykonywania funkcji zapisywania i ładowania Docker (wypróbowany i przetestowany):

Docker Save:

#!/bin/bash

#files will be saved in the dir 'Docker_images'
mkdir Docker_images
cd Docker_images
directory=`pwd`
c=0
#save the image names in 'list.txt'
doc= docker images | awk '{print $1}' > list.txt
printf "START \n"
input="$directory/list.txt"
#Check and create the image tar for the docker images
while IFS= read -r line
do
     one=`echo $line | awk '{print $1}'`
     two=`echo $line | awk '{print $1}' | cut -c 1-3`
     if [ "$one" != "<none>" ]; then
             c=$((c+1))
             printf "\n $one \n $two \n"
             docker save -o $two$c'.tar' $one
             printf "Docker image number $c successfully converted:   $two$c \n \n"
     fi
done < "$input"

Obciążenie dokera:

#!/bin/bash

cd Docker_images/
directory=`pwd`
ls | grep tar > files.txt
c=0
printf "START \n"
input="$directory/files.txt"
while IFS= read -r line
do
     c=$((c+1))
     printf "$c) $line \n"
     docker load -i $line
     printf "$c) Successfully created the Docker image $line  \n \n"
done < "$input"
Syed Faraz Umar
źródło
0

Możesz użyć jedno-liniowej ze DOCKER_HOSTzmienną:

docker save app:1.0 | gzip | DOCKER_HOST=ssh://user@remotehost docker load
witalność
źródło