一个Docker容器如何使用另一个以可执行文件而非服务形式构建的Docker容器

时间:2019-04-30 17:30:48

标签: node.js docker docker-compose

目标:

运行容器“ A”,基本上是一个nodejs服务器。该服务器应运行在另一个运行容器中公开的可执行文件,例如“ E”。

用简化代码。 “ A”包含使用“ E”的代码片段。

const spawn = require('child_process').spawn;

const someArgsForE = {
  arg1:"some_string",
  arg2:123
};

// E is the executable that would be normally run as 'docker run E '{ arg1:"some_string", arg2:123}' ... (ignore the correct escaping)
let childProcess = spawn("E", [JSON.stringify(someArgsForE)]);

childProcess.on('close', (code, signal) => {
  //do whatever with the result... maybe write in a volume
});

理想情况下,“ A”可以实现一些逻辑,以便它可以知道“ E”的存在。

If(serviceExists("E")){ ... do whatever ...}

由于可能还存在另一个“ E_b”可执行文件,并且由同一服务器“ A”使用。

我无法弄清楚如何使用 docker-compose 来实现此目标,而无需将“ E”以及可能的“ E_b”包装到其他nodejs服务中,而是将它们作为可执行文件进行访问。

要在docker内部安装docker并使用类似的东西

let childProcess = spawn("docker", ["run", "E", args]);

也不理想。

任何干净的可能解决方案?

1 个答案:

答案 0 :(得分:1)

如果不给服务提供对主机的无限根级别访问权限,这是不可能的。通常,您不是要向具有面向网络的服务的进程授予特权。

您所描述的最佳方法是通过仅向其中添加“ E”可执行文件来使“ A”图像自成一体。根据可执行文件的类型,您可能可以使用软件包管理器来安装它,或者以其他方式使其可用

FROM node

# Some things are installable via APT
RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
    apt-get install -y --no-install-recommends \
      e-executable

# Or sometimes you have an executable or tarball available locally
ADD f-executable.tar.gz /usr/local

# Routine stuff for a Node app
WORKDIR /app
COPY package.json yarn.lock .
RUN yarn install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

另一种方法是将主机的Docker套接字绑定安装到容器中。如前所述,这为服务提供了对主机的无限根级别访问。这种方法的常见陷阱包括允许调用者访问docker run -v /:/host ...的shell注入攻击,文件系统权限问题和目录映射问题,其中docker run -v选项的左侧始终是主机路径,即使它是从容器中发射。我强烈建议您避免使用此路径。