如何保存所有 Docker 镜像并复制到另一台机器
Posted
技术标签:
【中文标题】如何保存所有 Docker 镜像并复制到另一台机器【英文标题】:How to save all Docker images and copy to another machine 【发布时间】:2016-06-05 04:19:05 【问题描述】:我的系统上存在以下图像列表,并希望将所有这些图像复制到远程计算机。
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
u14_py269 latest 6a1ec0b508b3 4 days ago 885.9 MB
u12_py273 latest c2a804894851 4 days ago 686 MB
u12_core latest 0d61eba80df2 4 days ago 629.1 MB
c6_py266 latest cb1a94742d59 4 days ago 1.32 GB
c6_core latest 77c2ed19d87f 4 days ago 1.278 GB
c7_py275 latest bb1d3de68452 4 days ago 1.117 GB
c7_core latest ca14a76e9cca 4 days ago 1.081 GB
u14_py35 latest d110c7e4a1f5 5 days ago 914.5 MB
u14_py34 latest 085a37cb8614 5 days ago 830.7 MB
u14_py276 latest 8927c6167930 5 days ago 834.1 MB
u14_core latest 93ead5abc25b 5 days ago 776.9 MB
centos centos6 36877b5acebb 5 days ago 228.9 MB
ubuntu latest 36248ae4a9ac 5 days ago 188 MB
ubuntu 12.04 94a7cb19a65b 5 days ago 137.8 MB
edgester/gerrit latest ce4e3238052a 6 days ago 735.2 MB
u14_as374_py276 latest fa5fb7189d70 11 days ago 1.497 GB
c721_as373_py275 latest 03ccf6961d0c 11 days ago 844.3 MB
c721_as373_py35 latest b5fece3dd45b 11 days ago 1.127 GB
c171_con_core latest 8af0d24a38a0 2 weeks ago 377.2 MB
u14_as374_php55 latest 29df638e363a 3 weeks ago 1.073 GB
j_u14_as374_php55 latest 29df638e363a 3 weeks ago 1.073 GB
centos centos7 c8a648134623 8 weeks ago 196.6 MB
centos latest c8a648134623 8 weeks ago 196.6 MB
j_u14_as374_py276 latest 28f379d60882 10 weeks ago 871.5 MB
ubuntu 14.04 89d5d8e8bafb 10 weeks ago 187.9 MB
目前我正在使用save and load Docker images建议的方法,但我相信必须有更好的方法来处理所有图像。
【问题讨论】:
docker save/load
有什么问题?
@Auzias 在保存/加载方法中我将不得不一次处理 1 张图像,寻找一次处理所有图像的最佳方法。
这就是 bash 强大的原因。它可以迭代和执行循环。请参阅@kpie 的答案。一个命令行就足够了:docker save $(docker images -q)
@PavanGupta 你有没有找到更好的方法来自动化这个过程?
@Asme 不是真的,我只需要一次,但 Franklin Piat 的回应看起来很有希望。
【参考方案1】:
如果您想一次导出所有图像,请创建一个大 tar 文件:
docker save $(docker images -q) -o /path/to/save/mydockersimages.tar
如果你想在一个.tar
文件中保存多张图片:
IDS=$(docker images | awk 'if ($1 ~ /^(debian|centos)/) print $3')
docker save $IDS -o /path/to/save/somedockersimages.tar
最后,如果你想导出多张图片,每张图片有一个.tar
文件(磁盘效率不高:公共层保存在每个.tar
文件中):
docker images | awk 'if ($1 ~ /^(openshift|centos)/) print $1 " " $2 " " $3 ' | tr -c "a-z A-Z0-9_.\n-" "%" | while read REPOSITORY TAG IMAGE_ID
do
echo "== Saving $REPOSITORY $TAG $IMAGE_ID =="
docker save -o /path/to/save/$REPOSITORY-$TAG-$IMAGE_ID.tar $IMAGE_ID
done
您可能还想保存图像列表,以便可以标记恢复的图像:
docker images | sed '1d' | awk 'print $1 " " $2 " " $3' > mydockersimages.list
在远程机器上,您可以load
(导入)图片:
docker load -i /path/to/save/mydockersimages.tar
并标记导入的图像:
while read REPOSITORY TAG IMAGE_ID
do
echo "== Tagging $REPOSITORY $TAG $IMAGE_ID =="
docker tag "$IMAGE_ID" "$REPOSITORY:$TAG"
done < mydockersimages.list
有关保存/加载的更多信息,请阅读:How to copy Docker images from one host to another without using a repository
【讨论】:
我制作了一个巨大的焦油并加载了它。得到所有图像,但没有一个有存储库或标题/标签。现在我怎么知道我有什么图像? @Bsienn 花了这么多时间吗? @suhayab 不,在我的系统上花了大约 20 分钟。 请注意,如果您有没有任何标签<none>
的图像,使用上面提到的“保存标签脚本”可能会出现问题。或许额外的| grep -v '<none>'
可能已经在这里起到了作用。
我希望将通过 docker-compose.yml 创建的一组 6 个容器移动到另一台计算机。这种方法会奏效吗?它还会抓取所有卷吗?有必要吗?【参考方案2】:
使用 Windows 服务器托管的命令有点不同。使用#EthanSN 答案,我发现以下方法有效 - 使用 go 格式:
docker save $(docker images --format '.Repository:.Tag') -o allinone.tar
还有加载命令:
docker load -i allinone.tar
完美运行,无需导入机器下载任何图像。
【讨论】:
这个答案如果出于几个原因更可取。一:它不使用 sed 和 awk 来解析 docker 命令的输出,而是从一个命令到下一个命令生成正确的格式。二:在加载时保留标签,无需将它们保存在单独的文件中并在加载后重新标记图像。 这对于 Windows 操作系统来说是一个不错的解决方案,但这仅适用于 power shell 而不适用于 cmd 它说:来自守护进程的错误响应:无效的参考格式【参考方案3】:将所有带有name:tag
的图像保存到一个tar
文件中:
docker save $(docker images | sed '1d' | awk 'print $1 ":" $2 ') -o allinone.tar
然后,加载所有图像:
docker load -i allinone.tar
【讨论】:
简单干净的解决方案! @rfay 我认为这不是更好的方法,因为您将丢失所有标题和标签 @MarkMcDonagh 我检查了它,你是对的,我将删除关于使用docker images -q
误导的命令。
获取Error response from daemon: invalid reference format
@Zoinks 在哪一步?尝试拆分命令。 1.docker images | sed '1d' | awk 'print $1 ":" $2 '
2 docker save some_img:some_tag -o test.tar 3 docker load -i test.tar【参考方案4】:
非常感谢你们所有的遮阳篷,但我找到了一个基本且安全的解决方案to save:
docker save -o ubuntu.tar myjenk:latest jenkins/jenkins:lts
REPOSITORY TAG
myjenk latest
jenkins/jenkins lts
转至restore images:
docker load < ubuntu.tar
【讨论】:
【参考方案5】:执行 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"
【讨论】:
【参考方案6】:使用注册表,您可以拥有类似于 Git 的工作流程。在本地修改您的容器,将更改提交到本地映像,然后将您的映像推送到注册表。然后,您可以从远程计算机中提取图像。
您可以使用公共 Docker Hub,也可以设置自己的注册表服务器。
https://docs.docker.com/registry/
【讨论】:
如果远程服务器没有公共互联网访问权限,此解决方案将不起作用,但无论如何它很有用。 理想情况下,这应该是公认的答案,因为 docker 已经提供了实用程序。【参考方案7】:您可以使用 Bash 遍历对每个图像上运行 docker save -o <save image to path> <image name>
的 docker images
的响应,然后(假设您将它们全部保存到一个文件夹中)您可以将其压缩并通过 scp 将其发送到远程主机。
【讨论】:
以上是关于如何保存所有 Docker 镜像并复制到另一台机器的主要内容,如果未能解决你的问题,请参考以下文章