Docker镜像推送通过SSH(分布式)

时间:2015-07-22 23:10:10

标签: ssh docker docker-registry

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,对开发机器的依赖性很少,基本上只是Docker机器)
  • 部署到新的VPS,除了SSH访问和Docker守护程序之外,只有很少的依赖项。
  • 没有“永久”服务在任何地方运行,即我特别不希望托管永久运行的注册表(特别是所有VPS实例都无法访问,但这可能通过一些聪明的SSH隧道解决)

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

3 个答案:

答案 0 :(得分:30)

如果您想将docker镜像推送到给定的主机,Docker中已经存在允许这样做的所有内容。以下示例显示如何通过ssh推送docker镜像:

docker save <my_image> | ssh -C user@my.remote.host.com docker load
  • docker save将生成其中一个泊坞窗图像(包括其图层)的tar存档
  • -C用于压缩数据流的ssh
  • docker load从tar存档
  • 创建一个docker镜像

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

答案 1 :(得分: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   编辑。

     

根据您的操作系统,您的引擎后台程序启动选项。

     

编辑(或添加)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.

答案 2 :(得分:1)

我为此情况制作了一个命令行实用程序。

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

docker save相比,此方法的优势在于,只有新的图层才被推送到服务器,因此上传速度更快。

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

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

安装:

pip install docker-push-ssh

示例:

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

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

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