ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

我可以使用简单的命令吗?还是另一种解决方案?


G
Gautam Krishna R

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

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

通过 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 <image> | docker $(docker-machine config mach2) load 在机器 mach1mach2 之间复制图像。
@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'”)。
M
Martti Laine

要将图像保存到任何文件路径或共享 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>

v
vitalets

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

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

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

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

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

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

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

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

docker images

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

docker save awesomesauce:latest > awesomesauce.tar

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

现在从新主机做:

docker load < awesomesauce.tar

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


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

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

docker export CONTAINER_ID > my_container.tar

使用 cat my_container.tar | docker import - 导入所述图像。


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

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

最大的警告是您必须手动将 localhost 添加到 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 你能合并它吗?
J
John Kugelman

使用 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 子 shell 之一,以使用您当前的默认 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。


P
Peter Mortensen

我假设您需要保存图像 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

使用适用于您的环境的任何方法(例如 FTPSCP 等)将 archiveName.tar 文件复制到新的 Docker 实例。

在新 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


P
Peter Mortensen

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

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

q
quine9997

真实世界的例子

#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 服务?
它不适合我!收到此错误--->'打开/var/lib/docker/tmp/docker-import-315206241/app/json:没有这样的文件或目录'
P
Peter Mortensen

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

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

使用 docker save 保存图像,例如: docker save -o docker-images.tar app-web 使用 docker-machine scp docker-machine scp 复制图像 ./docker-images.tar remote-machine:/home/ubuntu

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

加载 Docker 镜像 docker-machine ssh remote-machine sudo docker load -i docker-images.tar


为什么不只是 'scp ' ?
K
Kaveh Naseri

保存所有图像的最佳方法是这样的:

docker save $(docker images --format '{{.Repository}}:{{.Tag}}') -o allimages.tar

上面的代码会将所有图像保存在 allimages.tar 中,并加载图像转到您保存图像的目录并运行以下命令:

docker load -i allimages.tar

只需确保在 power shell 而不是在 cmd 中使用此命令


T
Tarek Kalaji

通过 gzip 命令保存和加载 docker 镜像的最快方法:

docker save <image_id> | gzip > image_file.tgz

要在另一台服务器上加载您的压缩图像,请立即使用此命令,它将被识别为压缩图像:

docker load -i image_file.tgz

要重命名或重新标记图像,请使用:

docker image tag <image_id> <image_path_name>:<version>

例如:

docker image tag 4444444 your_docker_or_harbor_path/ubuntu:14.0

gzip 之后缺少 >。正确的命令模板:docker save <image_id> | gzip > image_file.tgz
V
Vikram

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

```
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 抓取的标准输入上。


r
runxc1 Bret Ferrier

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

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

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

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

C
Chu

您可以使用 sshfs

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

o
ofir_aghai

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

docker pull [选项] 名称[:TAG|@DIGEST]

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

泊坞窗保存 [选项] 图像 [图像...]

例如:

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

Y
Yoshi

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

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

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

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

无需手动压缩或类似。


S
Syed Faraz Umar

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

码头工人负载:

#!/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"