Docker over SSH

作者: 开心人开发世界 | 来源:发表于2019-11-19 10:49 被阅读0次

    我最近在我的一个业余项目中遇到了挑战。我需要将在一台机器上构建的docker容器转移到另一台可以通过SSH访问的机器上。我不想将我的容器推送到公共docker注册表,也不想设置自己的私有注册表。

    使用内置工具

    很快就在stack overflow找到了答案(https://stackoverflow.com/a/26226261/272958

    docker save <image> | bzip2 | \
         ssh user@host 'bunzip2 | docker load'
    

    让我们分解一下:

    1. docker save <image> 获取所有图像数据,并将其及其标签序列化为二进制数据流。
    2. docker load 接收二进制数据流并将其反序列化为带有标签的图像。
    3. bzip2压缩流并bunzip2解压缩流。
    4. ssh user@host 'some command' ssh进入远程主机并运行指定的命令。

    事实证明,docker load它能够自动解压缩bzip'd内容,因此您可以将命令简化为:

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

    您可以删除,bzip2但是docker映像通常很大,从进行压缩bzip2可以节省大量带宽。

    我仍然有一个问题。我通过慢速的3G Internet连接进行所有操作,并且远程主机已经具有要推送的映像中的大多数层,我只需要推送包含我的应用程序逻辑的微小新层即可。

    Pushing With Layers

    经过更多研究,我发现docker-push-ssh。使用此命令,您可以执行以下操作:

    docker-push-ssh user@host <image>
    

    它仅传输所需的层。为此:

    1. 在本地计算机上设置一个临时Docker注册表-这很容易做到,因为在名为docker的镜像中有一个docker注册表 registry:2
    2. 难道一个docker push到本地注册表。因为它遍及本地计算机的网络,所以速度很快。
    3. 使用SSH代理远程服务器上的端口,以便它连接到本地计算机上的代理。
    4. 难道一个docker pull远程服务器上。该拉取在SSH隧道上运行,但是docker pull非常聪明,仅拉取它尚不具备的层。

    我自己的解决方案

    这是一个好主意,但是我遇到了三个问题:

    1. 它是用Python编写的,并且需要Python 2.7,我不想依赖于已安装。
    2. 它已经有一段时间没有更新了,通常不会有什么问题,但是考虑到它依赖于旧版本的Python,这有点令人担忧。
    3. 目前尚不清楚远程计算机上所需的特权级别。我希望能够将事情锁定下来,以便进行推送的用户只能将特定的已命名docker映像推送到远程计算机,而不能做其他任何事情。

    为了解决所有这些问题,我决定在Node.js中创建一个名为docker-over-ssh的CLI 。尽管名称如此,但docker-over-ssh实际上完全与传输无关。它仅需要一种通过stdin和stdout与自身的远程实例进行通信的方法。要使用它,请docker-over-ssh同时在本地和远程计算机上安装。然后,您可以运行:

    docker-over-ssh push <image> \
      ssh user@host "docker-over-ssh pull <image>"
    

    该图看起来与先前的解决方案完全相同。

    docker-over-ssh push命令将启动本地docker注册表,将映像推送到其中,然后运行“子命令”(在本示例中为ssh user@host "docker-over-ssh pull <image>"),并将tcp流量从该子命令的stdio代理到本地docker注册表。

    docker-over-ssh pull <image>命令启动一个本地TCP代理(用几行node.js代码编写),并将该代理连接到stdio,以便它可以与本地docker注册表通信。然后,它docker pull指向本地注册表运行。仅传输新的层,从而使所有工作保持高效。

    用户唯一需要的许可是docker-over-ssh pull <image>在远程计算机上运行的能力,而无需任何其他操作。

    与CircleCI一起使用

    在这一点上,我有一个可行的解决方案,但是我想使它自动化,以便可以从CircleCI进行部署。向CircleCI添加SSH密钥非常容易。面临的挑战是如何通过其复杂的docker网络设置来完成这项工作:

    • 您的本地代码(即终止代理的node.js代码)无法与使用运行的容器对话docker run
    • docker守护进程(用于运行docker push)不能跟跑为主要CircleCI工作服务容器。

    我找不到直接解决这两个问题的任何实用方法,但是我发现NGROK可以很容易地创建一个可以访问本地服务的Internet访问地址。有了这个,我能够告诉CircleCI启动Docker注册表作为构建服务,然后使用ngrok启动一个临时代理以将其公开给docker守护程序。它甚至支持使用用户名和密码(由我自动生成)来保护它,以确保一切安全。

    最后,我要做的就是更新CircleCI配置:

    docker:
      - image: circleci/node:12
        environment:
          LOCAL_DOCKER_REGISTRY_PORT: '5000'
      - image: registry:2
    

    并将DOCKER_REGISTRY_NGROK环境变量设置为我的ngrok API密钥,您可以免费获取。

    然后,我向docker-over-ssh添加了一些代码来处理这两个环境变量。

    结论

    我做所有这些事情的原因是尝试安装一个dokku服务器,我可以在其中运行很多辅助项目,并避免在heroku上花费很少的金钱来处理很少使用的东西。我对这个问题的解决方案感到非常满意,但是由于Digital Ocean拥有托管的Kubernetes服务,而且价格似乎非常实惠,因此我现在决定研究Kubernetes 。这将需要我弄清楚运行具有某种身份验证/授权的持久性Docker注册表。

    翻译自:https://itnext.io/docker-over-ssh-51ab25a79f2e

    相关文章

      网友评论

        本文标题:Docker over SSH

        本文链接:https://www.haomeiwen.com/subject/ikkwictx.html