【问题标题】:How to copy Docker images from one host to another without using a repository如何在不使用存储库的情况下将 Docker 映像从一台主机复制到另一台主机
【发布时间】:2014-07-19 01:33:47
【问题描述】:

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

我在 VirtualBox 中创建了自己的镜像,完成后我尝试部署到其他机器以进行实际使用。

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

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

【问题讨论】:

标签: docker


【解决方案1】:

您需要将 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

【讨论】:

  • 这是 images 的更好答案。
  • 另外,最好使用repo:tag 作为图像参考而不是image id。如果您使用image id,则加载的图像将不会保留标签(并且您必须执行另一个步骤来标记图像)。
  • 我使用了图像 id 而不是 name:tag 现在我坐在这里,加载图像并为 REPOSITORY 和 TAG 设置一个 。带回名称和标签的正确方法是什么? @wisbucky
  • 要标记,首先使用docker images标识IMAGE ID,然后使用docker tag DESIREDIMAGEID mycompany/myreponame。如果你的image id是591de551d6e4,你可以把image id缩写成:docker tag 59 mycompany/myreponame
  • @serge 根本没有,它甚至有一个使用 windows 路径的例子......
【解决方案2】:

通过 SSH 传输 Docker 映像,即时压缩内容:

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

请注意,docker load 会自动为您解压缩图像。支持gzipbzip2xz

pv 放在管道中间以查看传输情况也是一个好主意:

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

(关于pv的更多信息:home pageman page)。

@Thomas Steinbach 的重要说明:在高带宽上,bzip 将无法足够快地压缩。如果您可以以 10 MB/s 或更高的速度上传,gzip/gunzip 将比 bzip2 快得多。

如果您使用 3G 并且您的互联网速度很慢,@jgmjgm 建议您可以使用xz:它提供更高的压缩比。

【讨论】:

  • 使用docker-machine时,可以docker $(docker-machine config mach1) save &lt;image&gt; | docker $(docker-machine config mach2) loadmach1mach2机器之间复制镜像。
  • @manojlds eval $(docker-machine env dev) 适用于与单个 docker 主机的一般通信,但不适用于两台机器之间的复制,因为这涉及两个不同的 docker 主机/docker 机器。
  • 反向执行此操作(远程到本地):ssh target_server 'docker save image:latest | bzip2' | pv | bunzip2 | docker load
  • 当 docker 在目标机器上需要 sudo 时,有什么办法可以做到这一点?我试过(没有压缩)docker save my_img:v1 | ssh -t -t my_user@my_machine sudo docker load。如果没有“-t”开关,sudo 会报错 sudo: sorry, you must have a tty to run sudo;使用一个“-t”是相同的消息,因为 ssh 说 不会分配伪终端,因为 stdin 不是终端。 最后,使用两个“-t”,我得到的内容我终端上的 tar 文件(即图像)。有什么想法吗?
  • @JosefStark 我需要在编辑 sudoers 文件时添加“默认值:!requiretty”以停止来自 sudo 的“抱歉”消息。我不知道它有多大的不同,但我也在 user@host 后面加上引号(所以“[...] | ssh user@host 'bunzip2 | sudo docker load'”)。
【解决方案3】:

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

通过以下方式获取图像ID:

docker images

假设您有一个 id 为“matrix-data”的图像。

用id保存图片:

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

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

docker load -i <path to copied image file>

【讨论】:

    【解决方案4】:

    您可以使用带有DOCKER_HOST 变量的单行:

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

    【讨论】:

    • 这绝对是我一直在寻找的命令,我认为这个答案值得更多的爱
    • prereqs:远程(ssh-copy-id)上的 ssh 凭据设置以及本地和远程用户都需要在 docker 组中(sudo usermod -aG docker $USER)
    • 这里与ssh user@remotehost docker load 有任何(性能)​​差异吗?
    【解决方案5】:

    首先将 Docker 镜像保存到压缩存档中:

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

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

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

    【讨论】:

    • 对于加载,docker load &lt; my-image.tar.gz 就足够了。对于 gzip、bzip2 和 xz,图像会自动解压缩。
    【解决方案6】:

    运行

    docker images
    

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

    docker save awesomesauce:latest > awesomesauce.tar
    

    将 tar 文件复制到 U 盘或其他任何东西,然后将其复制到新主机。

    现在从新主机做:

    docker load < awesomesauce.tar
    

    现在去喝杯咖啡阅读Hacker News...

    【讨论】:

    • 这里值得注意的是,这只有在保存和加载在同一个操作系统上执行时才有效。使用docker save [image] -o file.tardocker load -i file.tar 来避免这种情况!
    • docker save [image] -o file.tar 似乎也快得多
    • @AndreasForslöw 为什么使用管道意味着这只适用于同一个操作系统?
    【解决方案7】:

    对于容器文件系统的扁平化导出,请使用;

    docker export CONTAINER_ID &gt; my_container.tar

    使用cat my_container.tar | docker import - 导入该图片。

    【讨论】:

    • 根据cmd帮助本地导入为cat my_container.tar | docker import - my_container:new
    • 这更多的是用于备份正在运行的容器,而不是用于部署映像。
    • 我在 ubuntu 机器上尝试了 docker save,所有 docker 镜像都启动并运行良好。然后我将它们加载到 Windows 机器上。当我 docker run 或启动它们时有很多错误。有什么想法吗?
    【解决方案8】:

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

    它在服务器上建立一个临时的私有 Docker 注册表,从你的 localhost 建立一个 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

    最大的警告是您必须手动将本地主机添加到 Docker 的 insecure_registries 配置中。运行该工具一次,它会给您一个信息性错误:

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

    Where should I set the '--insecure-registry' flag on Mac OS?

    【讨论】:

    • 这是一个很有前途的实用程序。是否有任何其他答案提供仅复制更新层的解决方案?但是,我必须解决 a) 不支持 py3,b) 必须指定 ssh 识别文件,尽管我的位于默认位置,c) 端口 5000 已在我的服务器上使用,并且无法更改为另一个端口.
    • @nmgeek 考虑对 GitHub 上的实用程序进行 PR,以便其他人可以从您的更改中受益。
    • Python3 有 PR:github.com/brthor/docker-push-ssh/pull/15@brthornbury 你能合并吗?
    【解决方案9】:

    使用 docker-machine 时,您可以在机器 mach1mach2 之间复制图像:

    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】:

      我假设您需要保存图像 ID 为 7ebc8510bc2c 的 couchdb-cartridge

      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 文件复制到您的新 Docker 实例,例如 FTPSCP 等。

      在您的新 Docker 实例上运行 docker load 命令并指定映像 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
      

      请找到这个detailed post

      【讨论】:

        【解决方案11】:

        要将映像从本地 Docker 安装传输到 minikube VM:

        docker save <image> | (eval $(minikube docker-env) && docker load)
        

        【讨论】:

          【解决方案12】:

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

          从 Docker Machine v0.3.0 开始,引入了 scp 来将文件从一台 Docker 机器复制到另一台机器。如果您想将文件从本地计算机复制到远程 Docker 机器(例如 AWS EC2 或 Digital Ocean),这非常方便,因为 Docker 机器会为您处理 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
            

          【讨论】:

          • 为什么不只是'scp '?
          【解决方案13】:

          真实世界的例子

          #host1
          systemctl stop docker
          systemctl start docker
          docker commit -p 1d09068ef111 ubuntu001_bkp3
          #create backup
          docker save -o ubuntu001_bkp3.tar ubuntu001_bkp3
          
          #upload ubuntu001_bkp3.tar to my online drive
          aws s3 cp ubuntu001_bkp3.tar s3://mybucket001/
          
          
          #host2
          systemctl stop docker
          systemctl start docker
          cd /dir1
          
          #download ubuntu001_bkp3.tar from my online drive
          aws s3 cp s3://mybucket001/ubuntu001_bkp3.tar /dir1
          
          #restore backup
          cat ./ubuntu001_bkp3.tar  | docker load
          docker run --name ubuntu001 -it ubuntu001_bkp3:latest bash
          docker ps -a
          docker attach ubuntu001
          
          
          
          
          

          【讨论】:

          • 为什么在你做任何事情之前停止 docker 服务?
          • 它对我不起作用!!收到此错误 --- > 'open /var/lib/docker/tmp/docker-import-315206241/app/json: no such file or directory'
          【解决方案14】:

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

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

          解释:

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

          此外,这可以使用 gzip 压缩。在目标上,运行:

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

          tar-O 选项将内容放在标准输入上,docker load 可以获取这些内容。

          【讨论】:

            【解决方案15】:

            您可以使用sshfs:

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

            【讨论】:

              【解决方案16】:

              如果您在 Windows 机器上工作并上传到 linux 机器上的命令,例如

              docker save <image> | ssh user@host docker load
              

              如果您使用的是 powershell,它将不起作用,因为它似乎在输出中添加了一个额外的字符。但是,如果您使用 cmd(命令提示符)运行该命令,它将起作用。作为旁注,您还可以使用 Chocolatey 安装 gzip,以下内容也可以从 cmd 运行。

              docker save <image> | gzip | ssh user@host docker load
              

              【讨论】:

                【解决方案17】:

                执行 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"
                

                【讨论】:

                  【解决方案18】:

                  1.从注册表中提取图像或存储库。

                  docker pull [OPTIONS] 名称[:TAG|@DIGEST]

                  2。将其保存为 .tar 文件。

                  docker 保存 [OPTIONS] 图像 [图像...]

                  例如:

                  docker pull hello-world
                  docker save -o hello-world.tar hello-world
                  

                  【讨论】:

                    【解决方案19】:

                    根据@kolypto 的回答,这对我很有用,但只有sudo 用于docker load:

                    docker save <image> | bzip2 | pv | ssh user@host sudo docker load
                    

                    或者如果您没有/不想安装 pv:

                    docker save <image> | bzip2 | ssh user@host sudo docker load
                    

                    无需手动压缩或类似操作。

                    【讨论】:

                      猜你喜欢
                      • 2017-04-30
                      • 2015-03-25
                      • 1970-01-01
                      • 1970-01-01
                      • 2014-12-08
                      • 1970-01-01
                      相关资源
                      最近更新 更多