【问题标题】:Pass commands from one docker container to another将命令从一个 docker 容器传递到另一个
【发布时间】:2016-09-07 18:16:17
【问题描述】:

我有一个帮助容器和一个应用容器。

帮助容器处理通过 git 将代码挂载到与应用容器共享的挂载。

我需要帮助容器检查克隆代码中的package.jsonrequirements.txt,如果存在则运行npm installpip install -r requirements.txt,将依赖项存储在共享挂载中。 问题是 npm 命令和/或 pip 命令需要从应用容器运行,以保持帮助容器尽可能通用和不可知。

一种解决方案是将 docker 套接字安装到辅助容器并运行 docker exec <command> <app container>,但如果我在单个主机上拥有数千个这样的应用程序怎么办。 是否会有数百个容器同时访问 docker 套接字的问题?有没有更好的方法来做到这一点?让命令在另一个容器上运行?

【问题讨论】:

  • 您对帮助容器角色的描述听起来应该是您构建应用容器的映像。
  • 不,它公开了一个端点,我在内部用作 gogs 的 webhook,然后将文件克隆到共享挂载。
  • 嗯,好的,在您的容器中运行通常在镜像构建中的任务。它不会改变您的问题,如果您正在构建图像,您仍然需要从 webhook 容器触发构建。如果您有 100 个相同应用程序的实例,您将运行更少的命令。

标签: python node.js linux git docker


【解决方案1】:

嗯,没有像“ssh”这样的“容器到容器”内部通信层。在这方面,容器与 2 个不同的 VM 一样独立(通常在网络部分旁边)。

您可能会采用通常的方式,在“接收”服务器上安装 opensshd-server,仅基于密钥进行配置。您不需要将端口导出到主机,只需使用 docker-internal 网络连接到端口即可。在容器启动时间(卷挂载)期间,将 ssh 私钥部署在“调用方服务器”上,将公钥部署到“接收服务器”上的 .ssh/authorized_keys 中,这样您就不会在镜像中保留秘密(构建时间)。

可能还会在 .ssh/config 中创建一个 ssh 别名并将 HostVerify 设置为 no,因为可以重建容器。然后做

ssh <alias> your-command

【讨论】:

  • 这是一种方法。但是,这意味着安装 openssh 并弄乱密钥。将容器视为虚拟机确实有点澄清,如果毫无疑问它们是虚拟机,ssh 将是我的首选。有关安装 docker 套接字的缺点的任何信息?
  • 我听说过 docker-socket 方式 + 使用 docker exec,但我认为这是一个严重的安全漏洞。如果有人超越了您的“调用者”服务器,他将能够访问您主机上的每个 docker 容器,而不仅仅是当前应用程序 docker 堆栈中的那些。它是一个完全访问所有 docker-container-running 的方式 - 很多
  • 有道理,但是如果套接字仅安装在辅助容器上,应用容器中正在运行的应用程序除了共享已安装的文件夹之外没有任何迭代。这样可以吗?
  • 如果你在那里安装了套接字并且攻击者可以访问这个 docker-container,他可以使用套接字访问主机上的每个容器——不管你只安装了套接字“在这个container" - 所有容器的主机套接字
  • 事情是,如果攻击者没有利用正在运行的应用程序容器中的一些错误来访问挂载套接字的辅助容器,则访问辅助容器的唯一其他方法是从主机和我想如果攻击者可以访问主机,他们可能会做很多更糟糕的事情,并且已经可以访问所有容器。
【解决方案2】:

找到了我正在寻找的更好的方法:-)。

使用 supervisord 并运行 xml rpc 服务器使我能够运行以下内容:

supervisorctl -s http://127.0.0.1:9002 -utheuser -pthepassword start uwsgi supervisorctl -s http://127.0.0.1:9002 -utheuser -pthepassword start uwsgi

在 helper 容器中,这将连接到在 app 容器的 9002 端口上运行的 rpc 服务器,并执行一个可能看起来像这样的程序块;

[program:uwsgi]
directory=/app
command=/usr/sbin/uwsgi --ini /app/app.ini --uid nginx --gid nginx --plugins http,python --limit-as 512
autostart=false
autorestart=unexpected
stdout_logfile=/var/log/uwsgi/stdout.log
stdout_logfile_maxbytes=0
stderr_logfile=/var/log/uwsgi/stderr.log
stderr_logfile_maxbytes=0
exitcodes=0
environment = HOME="/app", USER="nginx"]

这正是我需要的!

对于发现此问题的任何人,您可能需要您的应用容器上的 supervisord.conf 看起来像:

[supervisord]
nodaemon=true

[supervisorctl]

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[inet_http_server]
port=127.0.0.1:9002
username=user
password=password

[program:uwsgi]
directory=/app
command=/usr/sbin/uwsgi --ini /app/app.ini --uid nginx --gid nginx --plugins http,python --limit-as 512
autostart=false
autorestart=unexpected
stdout_logfile=/var/log/uwsgi/stdout.log
stdout_logfile_maxbytes=0
stderr_logfile=/var/log/uwsgi/stderr.log
stderr_logfile_maxbytes=0
exitcodes=0
environment = HOME="/app", USER="nginx"]

您可以设置 inet_http_server 以侦听套接字。您可以链接容器以便能够通过主机名访问它们。

【讨论】:

    猜你喜欢
    • 2021-04-07
    • 2020-03-20
    • 1970-01-01
    • 2018-10-08
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    相关资源
    最近更新 更多