如何在不使用存储库的情况下将Docker映像从一台主机复制到另一台主机


1372

如何在不使用存储库的情况下将Docker映像从一台计算机转移到另一台计算机,无论是私有的还是公共的?

我在VirtualBox中创建自己的映像,完成后,我尝试部署到其他计算机上以实际使用。

由于它基于我自己的映像(例如Red Hat Linux),因此无法从Dockerfile重新创建。我的dockerfile不容易移植。

我可以使用简单的命令吗?还是其他解决方案?

Answers:


2301

您将需要将Docker映像另存为tar文件:

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

那么你的图像复制到与普通文件传输工具,如一个新的系统cpscprsync(首选大文件)。之后,您必须将映像加载到Docker中:

docker load -i <path to image tar file>

PS:您可能需要sudo所有命令。

编辑:您应该使用-o添加文件名(而不仅仅是目录),例如:

docker save -o c:/myfile.tar centos:16

27
对于图像,这是更好的答案。
安迪2014年

26
同样,最好将其repo:tag用作图像参考,而不是image id。如果使用image id,则加载的图像将不会保留标签(您将不得不执行另一步骤来标记图像)。
wisbucky

1
我使用图像ID代替了名称:tag现在,我坐在这里,加载图像,并对REPOSITORY和TAG设置<none>。带回名称和标签的正确方法是什么?@wisbucky
Ulfhetnar

3
要进行标记,请先使用来标识IMAGE ID docker images,然后使用docker tag DESIREDIMAGEID mycompany/myreponame。如果您的图像ID为591de551d6e4,则可以缩写该图像ID:docker tag 59 mycompany/myreponame
JuniorMayhé18年

@AndiJay看看如何将
pipe_tape_coder

582

通过SSH传输Docker映像,并即时bzip内容:

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

pv将管道置于管道中间以查看传输过程也是一个好主意:

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

(有关更多信息pv主页手册页)。


19
使用docker-machine时,您可以docker $(docker-machine config mach1) save <image> | docker $(docker-machine config mach2) load在机器mach1mach2之间复制映像。
matlehmann

5
@manojlds eval $(docker-machine env dev)适合与单个docker 主机进行常规通信,但不能在两台机器之间进行复制,因为这涉及两个不同的docker主机/ docker机器。
matlehmann

14
反向执行此操作(远程操作):ssh target_server 'docker save image:latest | bzip2' | pv | bunzip2 | docker load
ThorSummoner '16

2
当docker在目标机器上要求sudo时,有什么方法可以做到这一点?我尝试过(无压缩)docker save my_img:v1 | ssh -t -t my_user@my_machine sudo docker load。没有“ -t”开关,sudo抱怨sudo:对不起,您必须有一个tty才能运行sudo。用一个“ -t”表示相同的消息,因为ssh表示将不会分配伪终端,因为stdin不是终端。最后,用两个“ -t”在终端上获取tar文件的内容(即图像)。有任何想法吗?
饥饿

1
@JosefStark我需要在编辑sudoers文件时添加“默认值:<目标用户名>!requiretty”,以停止来自sudo的“抱歉”消息。我不知道它有什么区别,但是我也将user @ host后面的所有内容都用引号引起来(因此,“ [...] | ssh user @ host'bunzip2 | sudo docker load'”)。
VirtualWolf

99

要将图像保存到任何文件路径或共享NFS位置,请参见以下示例。

通过执行以下操作获取图像ID:

sudo docker images

假设您有一个ID为“矩阵数据”的图片。

保存具有ID的图片:

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

将映像从路径复制到任何主机。现在,使用以下命令导入到本地Docker安装:

sudo docker load -i <path to copied image file>

34

首先将Docker映像保存到一个zip文件中:

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

然后使用以下命令将导出的映像加载到Docker:

zcat <docker image name>.tar.gz | docker load

11
对于加载,docker load < my-image.tar.gz就足够了。图像会自动针对gzip,bzip2和xz解压缩。
Flux

32

docker images

查看主机上的图像列表。假设您有一个名为awesomesauce的图像。在终端中,cd将图像导出到的目录。现在运行:

docker save awesomesauce:latest > awesomesauce.tar

将tar文件复制到拇指驱动器或其他驱动器,然后将其复制到新的主机。

现在,从新主机执行:

docker load < awesomesauce.tar

现在去喝咖啡,阅读黑客新闻 ...


4
值得一提的是,只有在同一OS上执行保存和加载时,此方法才有效。使用docker save [image] -o file.tardocker load -i file.tar避免这种情况!
AndreasForslöw,

docker save [image] -o file.tar也似乎要快得多
ti7


15

当使用泊坞窗机,您可以复制机之间的图像mach1,并mach2用:

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

当然,您也可以停留pv在中间以获取进度指示器:

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

您也可以省略其中一个docker-machine config子外壳,以使用当前的默认docker-host。

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

将图像从当前docker-host复制到 mach

要么

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

复制mach到当前的docker-host。


10

我假设您需要保存couchdb-cartridge的图像ID为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

将archiveName图像保存到tar文件。我将使用/media/sf_docker_vm/保存图像。

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

在您的环境中使用任何方法的作品中,archiveName.tar文件复制到新的码头工人的实例,例如FTPSCP等等。

docker load在新的Docker实例上运行命令,并指定映像tar文件的位置。

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

最后,运行docker images命令以检查图像现在可用。

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

请找到这个详细的帖子



10

docker-push-ssh 是我为此场景创建的命令行实用程序。

它在服务器上设置了一个临时的私有Docker注册表,从您的本地主机建立SSH隧道,推送您的映像,然后对其进行清理。

这种方法的优势docker save(在撰写本文时,大多数答案都在使用此方法)是,只有新的层被推送到服务器,从而可以更快地上传。

通常不希望使用诸如dockerhub之类的中间注册表,而且很麻烦。

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

安装:

pip install docker-push-ssh

例:

docker-push-ssh -i ~/my_ssh_key username@myserver.com my-docker-image

最大的警告是您必须手动将localhost添加到Docker的insecure_registries配置中。运行该工具一次,它将给您一个提示错误:

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

我应该在Mac OS的哪里设置“ --insecure-registry”标志?


1
我编辑了您的答案,以明确表明您所推荐的实用程序是由您创建的。请参阅此页面,尤其是:“发布好的相关问题的答案,并且如果某些(但不是全部)碰巧与您的产品或网站有关,那就可以了。但是,您必须在答案中披露与您的隶属关系。”
路易

8

所有其他答案都非常有帮助。我只是遇到了同样的问题,并想出了一个简单的方法docker machine scp

自Docker Machine v0.3.0起,引入了scp将文件从一台Docker计算机复制到另一台Docker计算机。如果要将文件从本地计算机复制到远程Docker计算机(例如AWS EC2或Digital Ocean),这将非常方便,因为Docker Machine正在为您处理SSH凭据。

  1. 使用以下方式保存图像docker save

    docker save -o docker-images.tar app-web
    
  2. 使用docker-machine scp复制图像

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

假设您的远程Docker计算机为remote-machine,而您希望tar文件所在的目录为/home/ubuntu

  1. 加载Docker镜像

    docker-machine ssh remote-machine sudo docker load -i docker-images.tar
    

5
为什么不只是'scp <source> <remote>'?
塔马斯·卡尔曼

3

我想移动所有带有标签的图像。

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

说明:

首先OUT获取所有标签,但用新行分隔。Second OUTPUT获取数组中的所有标签。第三,$(echo "${OUTPUT[*]}")将所有标记放在一个docker save命令中,以便所有图像都在单个tar中。

此外,可以使用gzip将其压缩。按目标运行:

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

-O选项tar将内容放在stdin上,可以被docker load


2

您可以使用sshfs

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

1

用于执行Docker保存和加载功能的脚本(经过测试)

Docker保存:

#!/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负载:

#!/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"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.