Comment copier des images Docker d'un hôte à un autre sans utiliser de référentiel

1375

Comment transférer une image Docker d'une machine à une autre sans utiliser de référentiel, qu'il soit privé ou public?

Je crée ma propre image dans VirtualBox, et quand elle est terminée, j'essaie de déployer sur d'autres machines pour avoir une utilisation réelle.

Puisqu'il est basé sur ma propre image (comme Red Hat Linux), il ne peut pas être recréé à partir d'un Dockerfile. Mon dockerfile n'est pas facilement portable.

Y a-t-il des commandes simples que je peux utiliser? Ou une autre solution?

Larry Cai
la source

Réponses:

2312

Vous devrez enregistrer l'image Docker en tant que fichier tar:

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

Copiez ensuite votre image sur un nouveau système avec des outils de transfert de fichiers réguliers tels que cp, scpou rsync(préféré pour les gros fichiers). Après cela, vous devrez charger l'image dans Docker:

docker load -i <path to image tar file>

PS: Vous devrez peut-être sudotoutes les commandes.

EDIT: Vous devez ajouter le nom de fichier (pas seulement le répertoire) avec -o, par exemple:

docker save -o c:/myfile.tar centos:16
Daiwei
la source
27
C'est la meilleure réponse pour les images .
Andy
26
il est également préférable de l'utiliser repo:tagcomme référence d'image plutôt que image id. Si vous utilisez image id, l'image chargée ne conservera pas la balise (et vous devrez effectuer une autre étape pour baliser l'image).
wisbucky
1
J'ai utilisé l'ID d'image au lieu du nom: tag Maintenant, je suis assis ici, j'ai chargé l'image et j'ai un <aucun> pour REPOSITORY et TAG. Quelle est la bonne façon de ramener le nom et la balise? @wisbucky
Ulfhetnar
3
Pour baliser, identifiez d'abord l'ID IMAGE à l'aide de docker images, puis utilisez docker tag DESIREDIMAGEID mycompany/myreponame. Si votre ID d'image est 591de551d6e4, vous pouvez abréger l'ID d'image:docker tag 59 mycompany/myreponame
Junior Mayhé
@AndiJay Jetez un œil à Comment copier des images de docker d'un hôte à un autre?
duct_tape_coder
582

Transférer une image Docker via SSH, compresser le contenu à la volée:

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

C'est aussi une bonne idée de mettre pvau milieu du tuyau pour voir comment se passe le transfert:

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

(Plus d'informations sur pv: page d'accueil , page de manuel ).

kolypto
la source
19
Lorsque vous utilisez docker-machine, vous pouvez faire docker $(docker-machine config mach1) save <image> | docker $(docker-machine config mach2) loadpour copier des images entre les machines mach1 et mach2 .
matlehmann
5
@manojlds eval $(docker-machine env dev)est bon pour la communication générale avec un seul hôte Docker mais pas pour copier entre deux machines, car cela implique deux hôtes Docker / machines Docker différents.
matlehmann
14
pour faire cela en sens inverse (de distance au local):ssh target_server 'docker save image:latest | bzip2' | pv | bunzip2 | docker load
ThorSummoner
2
Existe-t-il un moyen de le faire lorsque Docker nécessite sudo sur la machine cible? J'ai essayé (sans compression) docker save my_img:v1 | ssh -t -t my_user@my_machine sudo docker load. Sans le commutateur "-t", sudo se plaint sudo: désolé, vous devez avoir un tty pour exécuter sudo ; avec un "-t" c'est le même message car ssh dit que le pseudo-terminal ne sera pas alloué car stdin n'est pas un terminal. et enfin, avec deux "-t", j'obtiens le contenu du fichier tar (ie l'image) sur mon terminal. Des idées?
faim
1
@JosefStark J'avais besoin d'ajouter "Valeurs par défaut: <nom d'utilisateur cible>! Requireetty" lors de la modification du fichier sudoers pour arrêter le message "Désolé" de sudo. Je ne sais pas à quel point cela fait une différence, mais j'ai également mis tout après l'utilisateur @ host entre guillemets (donc "[...] | ssh user @ host 'bunzip2 | sudo docker load'").
VirtualWolf
99

Pour enregistrer une image dans n'importe quel chemin de fichier ou emplacement NFS partagé, consultez l'exemple suivant.

Obtenez l'identifiant de l'image en faisant:

sudo docker images

Supposons que vous ayez une image avec l'ID "matrice-données".

Enregistrez l'image avec l'identifiant:

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

Copiez l'image du chemin vers n'importe quel hôte. Maintenant, importez dans votre installation Docker locale en utilisant:

sudo docker load -i <path to copied image file>
Sohan
la source
34

Enregistrez d'abord l'image Docker dans un fichier zip:

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

Chargez ensuite l'image exportée dans Docker à l'aide de la commande ci-dessous:

zcat <docker image name>.tar.gz | docker load
Damodaran
la source
11
Pour le chargement, docker load < my-image.tar.gzc'est suffisant. L'image est décompressée automatiquement pour gzip, bzip2 et xz.
Flux
32

Courir

docker images

pour voir une liste des images sur l'hôte. Disons que vous avez une image appelée awesomesauce . Dans votre terminal, cdvers le répertoire dans lequel vous souhaitez exporter l'image. Maintenant, lancez:

docker save awesomesauce:latest > awesomesauce.tar

Copiez le fichier tar sur une clé USB ou autre, puis copiez-le sur le nouvel ordinateur hôte.

Maintenant, depuis le nouvel hôte, faites:

docker load < awesomesauce.tar

Maintenant, allez prendre un café et lisez Hacker News ...

Neil Girardi
la source
4
Il convient de noter ici que cela ne fonctionnera que si la sauvegarde et le chargement sont exécutés sur le même système d'exploitation. Utilisez docker save [image] -o file.taret docker load -i file.tarpour éviter cela!
Andreas Forslöw
docker save [image] -o file.tarsemble également être beaucoup plus rapide
ti7
19

Pour une exportation aplatie du système de fichiers d'un conteneur, utilisez;

docker export CONTAINER_ID > my_container.tar

Utilisez cat my_container.tar | docker import -pour importer ladite image.

Panagiotis Moustafellos
la source
9
ce sera le cat my_container.tar | docker import - my_container:newcas si vous importez localement selon l'aide de cmd
Larry Cai
7
C'est plus pour sauvegarder un conteneur en cours d'exécution que pour déployer une image.
Kousha
15

Lorsque vous utilisez docker-machine, vous pouvez copier des images entre des machines mach1et mach2avec:

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

Et bien sûr, vous pouvez également rester pvau milieu pour obtenir un indicateur de progression:

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

Vous pouvez également omettre l'un des docker-machine configsous-shells pour utiliser votre docker-host par défaut actuel.

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

pour copier l'image de l'hôte docker actuel vers mach

ou

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

à copier depuis l' machhôte docker actuel.

matlehmann
la source
10

Je suppose que vous devez enregistrer couchdb-cartridgeun ID d'image 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

Enregistrez l'image archiveName dans un fichier tar. J'utiliserai le /media/sf_docker_vm/pour enregistrer l'image.

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

Copiez le fichier archiveName.tar à votre nouvelle instance de Docker en utilisant quelles que soient les œuvres méthode dans votre environnement, par exemple FTP, SCPetc.

Exécutez la docker loadcommande sur votre nouvelle instance Docker et spécifiez l'emplacement du fichier tar d'image.

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

Enfin, exécutez la docker imagescommande pour vérifier que l'image est désormais disponible.

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

Veuillez trouver cet article détaillé .

tk_
la source
10

Pour transférer des images de votre installation Docker locale vers une machine virtuelle minikube:

docker save <image> | (eval $(minikube docker-env) && docker load)
Bryan Larsen
la source
10

docker-push-ssh est un utilitaire de ligne de commande que j'ai créé juste pour ce scénario.

Il met en place un registre Docker privé temporaire sur le serveur, établit un tunnel SSH à partir de votre hôte local, pousse votre image, puis nettoie après lui-même.

L'avantage de cette approche docker save(au moment de la rédaction de la plupart des réponses utilise cette méthode) est que seules les nouvelles couches sont envoyées au serveur, ce qui entraîne un téléchargement beaucoup plus rapide.

Souvent, l'utilisation d'un registre intermédiaire comme dockerhub est indésirable et lourde.

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

Installer:

pip install docker-push-ssh

Exemple:

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

La plus grande mise en garde est que vous devez ajouter manuellement votre hôte local à la insecure_registriesconfiguration de Docker . Exécutez l'outil une fois et il vous donnera une erreur informative:

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

Où dois-je définir l'indicateur «--insecure-registry» sous Mac OS?

brthornbury
la source
1
J'ai modifié votre réponse pour indiquer clairement que l'utilitaire que vous recommandez a été créé par vous. Consultez cette page , en particulier: "Publiez de bonnes réponses pertinentes et si certaines (mais pas toutes) concernent votre produit ou votre site Web, ce n'est pas grave. Cependant, vous devez divulguer votre affiliation dans vos réponses."
Louis
8

Toutes les autres réponses sont très utiles. Je viens de traverser le même problème et de trouver un moyen facile de le faire docker machine scp.

Depuis Docker Machine v0.3.0, scp a été introduit pour copier des fichiers d'une machine Docker vers une autre. Cela est très pratique si vous souhaitez copier un fichier de votre ordinateur local vers une machine Docker distante comme AWS EC2 ou Digital Ocean, car Docker Machine s'occupe des informations d'identification SSH pour vous.

  1. Enregistrez vos images en utilisant docker savecomme:

    docker save -o docker-images.tar app-web
    
  2. Copier des images à l'aide de docker-machine scp

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

Supposons que votre machine Docker distante soit remote-machineet que le répertoire dans lequel vous voulez que le fichier tar soit /home/ubuntu.

  1. Charger l'image Docker

    docker-machine ssh remote-machine sudo docker load -i docker-images.tar
    
Peng
la source
5
pourquoi pas simplement 'scp <source> <remote>'?
Tamas Kalman
3

Je souhaite déplacer toutes les images avec des balises.

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

Explication:

OUTObtient d' abord toutes les balises mais séparées par de nouvelles lignes. La seconde OUTPUTobtient toutes les balises d'un tableau. Troisième $(echo "${OUTPUT[*]}")place toutes les balises pour une seule docker savecommande afin que toutes les images soient dans un seul tar.

De plus, cela peut être compressé à l'aide de gzip. Sur cible, exécutez:

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

-Ooption pour mettre le tarcontenu sur stdin qui peut être saisi par docker load.

Vikram
la source
2

Vous pouvez utiliser sshfs:

$ sshfs user@ip:/<remote-path> <local-mount-path>
$ docker save <image-id> > <local-mount-path>/myImage.tar
Chu
la source
1

Script pour exécuter la fonction de sauvegarde et de chargement de Docker (testé et testé):

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"

Docker Load:

#!/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
la source
0

Vous pouvez utiliser un one-liner avec DOCKER_HOSTvariable:

docker save app:1.0 | gzip | DOCKER_HOST=ssh://user@remotehost docker load
vitalets
la source