Docker镜像推送SSH(分布式)

Kru*_*lur 26 ssh docker docker-registry

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

docker push myimage ssh://myvps01.vpsprovider.net/
Run Code Online (Sandbox Code Playgroud)

我没有理解整个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服务器并重建它,但它减慢了部署,因为我每次都必须从源构建容器.

Tho*_*eil 36

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

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

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

  • 我知道加载和保存,但重点是聪明,只推动/拉动不同的层. (7认同)

brt*_*ury 6

我为这个场景制作了一个命令行实用程序。

它在服务器上设置一个临时的私有 docker 注册表,从您的本地主机建立一个 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

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

/sf/ask/2296575081/


NRJ*_*NRJ 6

扩展@brthornbury 的想法。

我不想涉足运行 python,所以我想出了同样的 bash 脚本。

#!/usr/bin/env bash
SOCKET_NAME=my-tunnel-socket
REMOTE_USER=user
REMOTE_HOST=my.remote.host.com

# open ssh tunnel to remote-host, with a socket name so that we can close it later
ssh -M -S $SOCKET_NAME -fnNT -L 5000:$REMOTE_HOST:5000 $REMOTE_USER@$REMOTE_HOST

if [ $? -eq 0 ]; then
  echo "SSH tunnel established, we can push image"
  # push the image to remote host via tunnel
  docker push localhost:5000/image:latest
fi
# close the ssh tunnel using the socket name
ssh -S $SOCKET_NAME -O exit $REMOTE_USER@$REMOTE_HOST
Run Code Online (Sandbox Code Playgroud)


Mar*_*kai 5

将图像保存/加载到 Docker 主机和推送到注册表(私有或集线器)是两件不同的事情。

前@Thomasleveil 已经解决了。

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

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

如果我们有两个图像,一个是从另一个派生的,那么执行:

docker tag baseimage myregistry:5000/baseimage
docker push myregistry:5000/baseimage
Run Code Online (Sandbox Code Playgroud)

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

docker tag derivedimage myregistry:5000/derivedimage
docker push myregistry:5000/derivedimage
Run Code Online (Sandbox Code Playgroud)

您可能会注意到只有一层被推送 - 前提是您的 Dockerfile 构建为只需要一层(例如,根据Dockerfile 最佳实践,链接 RUN 参数)。

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

请参阅容器化 Docker 注册表

据我所知,截至撰写本文时,注册表推/拉/查询机制不支持 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。

使用自签名证书

[...]
Run Code Online (Sandbox Code Playgroud)

这比不安全的注册表解决方案更安全。您必须配置每个想要访问您的注册表的 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.
Run Code Online (Sandbox Code Playgroud)