Docker镜像推送SSH(分布式)

问题描述 投票:23回答:3

TL; DR基本上,我正在寻找:

docker push myimage ssh://myvps01.vpsprovider.net/

我没有理解整个Docker Hub / Registry事件的基本原理。我知道我可以运行私有注册表,但为此我必须设置实际运行服务器的基础结构。

我偷偷摸摸看看Docker的内部工作(至少是文件系统),看起来Docker图像层只是一堆tarball,或多或少,有一些精心设计的文件命名。我天真地认为用一个简单的Python脚本来做分布式推/拉是不可能的,但当然我没有尝试,所以这就是我问这个问题的原因。

有没有任何技术原因为什么Docker不能像Git或Mercurial一样进行分布式(无服务器)推/拉?

我认为这将是一个巨大的帮助,因为我可以将我在笔记本电脑上构建的图像直接推送到应用服务器上,而不是首先推送到某个地方的repo服务器然后从应用服务器拉出来。或者我可能误解了这个概念,而且注册表是我绝对需要的一个非常重要的功能?

编辑一些有希望解释我为什么要这样做的上下文,请考虑以下场景:

  • 在我的笔记本电脑上进行开发,测试(OSX,运行Docker机器,使用docker-compose来定义服务和依赖项)
  • 通过脚本部署到实时环境(自编,bash,dev机器上的几个依赖,基本上只是Docker机器)
  • 除了SSH访问和Docker守护程序之外,部署到具有极少依赖性的新VPS。
  • 没有“永久”服务在任何地方运行,即我特别不希望托管永久运行的注册表(特别是所有VPS实例都无法访问,尽管这可能通过一些聪明的SSH隧道解决)

目前最好的解决方案是使用Docker机器指向VPS服务器并重建它,但它减慢了部署,因为我每次都必须从源构建容器。

ssh docker docker-registry
3个回答
32
投票

如果你想将docker镜像推送到给定的主机,Docker中已经有了所有这些功能。以下示例显示如何通过ssh推送docker镜像:

docker save <my_image> | ssh -C [email protected] docker load
  • docker save将生成一个docker镜像(包括其图层)的tar存档
  • -C用于压缩数据流的ssh
  • docker load从tar存档创建一个docker镜像

请注意,docker registry + docker pull命令的组合具有仅下载缺失层的优点。因此,如果您经常更新docker镜像(添加新图层或修改最后几个图层),那么docker pull命令将比通过ssh推送完整的docker图像产生更少的网络流量。


4
投票

将图像保存/加载到Docker主机并推送到注册表(私有或集线器)是两回事。

前@Thomasleveil已经解决了。

后者实际上确实具有“智能”,只能推动所需的层。

您可以使用私有注册表和一些派生图像轻松地自行测试。

如果我们有两个图像,一个来自另一个,那么:

docker tag baseimage myregistry:5000/baseimage
docker push myregistry:5000/baseimage

将推送尚未在注册表中找到的所有图层。但是,当您接下来推送派生图像时:

docker tag derivedimage myregistry:5000/derivedimage
docker push myregistry:5000/derivedimage

您可能会注意到只有一个图层被推送 - 只要您的Dockerfile构建为只需要一层(例如,根据Dockerfile Best Practises链接RUN参数)。

在Docker主机上,您还可以运行Dockerised私有注册表。

Containerized Docker registry

据我所知,在撰写本文时,注册表推/拉/查询机制不支持SSH,而只支持HTTP / HTTPS。这与Git和朋友不同。

有关如何通过HTTP运行私有注册表的信息,请参阅Insecure Registry,尤其要注意您需要更改Docker引擎选项并重新启动它:

打开/ etc / default / docker文件或/ etc / sysconfig / docker进行编辑。

您的Engine守护程序启动选项取决于您的操作系统。

编辑(或添加)DOCKER_OPTS行并添加--insecure-registry标志。

例如,此标志采用注册表的URL。

DOCKER_OPTS =“ - insecure-registry myregistrydomain.com:5000”

关闭并保存配置文件。

重新启动Docker守护程序

您还可以找到使用自签名证书的说明,允许您使用HTTPS。

使用自签名证书

[...]

这比不安全的注册表解决方案更安全。您必须配置要访问注册表的每个docker守护程序

Generate your own certificate:

mkdir -p certs && openssl req \ -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \ -x509 -days 365 -out certs/domain.crt

Be sure to use the name myregistrydomain.com as a CN.

Use the result to start your registry with TLS enabled

Instruct every docker daemon to trust that certificate.

This is done by copying the domain.crt file to /etc/docker/certs.d/myregistrydomain.com:5000/ca.crt.

Don’t forget to restart the Engine daemon.

3
投票

我为这个场景制作了一个命令行工具。

它在服务器上设置一个临时的私有docker注册表,从您的localhost建立一个SSH隧道,推送您的图像,然后自行清理。

这种方法优于docker save的好处是只有新层被推送到服务器,从而加快了上传速度。

通常使用像dockerhub这样的中间注册表是不可取的,也很麻烦。

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

安装:

pip install docker-push-ssh

例:

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

最大的警告是你必须手动将你的本地IP添加到docker的insecure_registries配置中。

https://stackoverflow.com/questions/32808215/where-to-set-the-insecure-registry-flag-on-mac-os

© www.soinside.com 2019 - 2024. All rights reserved.