30

有两个容器A和B。一旦容器A启动,将执行一个进程,然后容器将停止。容器 B 只是一个 Web 应用程序(比如 expressjs)。是否可以从容器 B 启动 A ?

4

3 回答 3

39

可以授予容器对 docker 的访问权限,以便它可以在您的主机上生成其他容器。您可以通过暴露容器内的 docker 套接字来做到这一点,例如:

docker run -v /var/run/docker.sock:/var/run/docker.sock --name containerB myimage ...

现在,如果您docker在容器内有可用的客户端,您将能够控制主机上的 docker 守护程序并使用它来生成您的“容器 A”。

在尝试这种方法之前,您应该了解安全注意事项:访问 docker 与root访问主机相同,这意味着如果您的 Web 应用程序有远程入侵,您只是将主机的密钥交给了攻击者。本文对此进行了更全面描述。

于 2016-09-13T12:17:23.703 回答
18

可以通过安装 docker 套接字来实现。

容器 A
它将时间打印到标准输出(及其日志)并退出。

docker run --name contA ubuntu date

容器 B
诀窍是挂载主机的 docker 套接字,然后在容器上安装 docker 客户端。然后它将与守护进程交互,就像您在主机上使用 docker 一样。安装 docker 后,它只需每 5 秒重新启动一次容器 A。

docker run --name contB -v /var/run/docker.sock:/var/run/docker.sock ubuntu bash -c "
apt-get update && apt-get install -y curl &&
curl -sSL https://get.docker.com/ | sh && 
watch --interval 5 docker restart contA"

您可以通过查看其日志看到 contA 正在被调用

docker logs contA

也就是说,Docker 确实适用于长期运行的服务。在 Docker github 问题上有一些关于为维护、cron 作业等指定短期“作业”服务的讨论,但没有任何决定,更不用说编码了。因此,最好构建您的系统,使容器保持正常运行。

于 2016-09-13T12:45:03.647 回答
3

docker-compose.yml(学分给 larsks)

# ...
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock
# ...

Dockerfile(学分亚伦五世)

# ...

ENV DOCKERVERSION=19.03.12
RUN curl -fsSLO https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKERVERSION}.tgz \
  && tar xzvf docker-${DOCKERVERSION}.tgz --strip 1 -C /usr/local/bin docker/docker \
  && rm docker-${DOCKERVERSION}.tgz

# ...

Node.js index.js(感谢 Arpan Abhishek、Maulik Parmar 和 anishsane)

# ...

const { exec } = require("child_process");

# ...

        exec('docker container ls -a --format "table {{.ID}}\t{{.Names}}" | grep <PART_OF_YOUR_CONTAINER_NAME> | cut -d" " -f1 | cut -f1 | xargs -I{} docker container restart -t 0 {}', (error, stdout, stderr) => {
            if (error) {
                console.log(`error: ${error.message}`);
                return;
            }
            if (stderr) {
                console.log(`stderr: ${stderr}`);
                return;
            }
            console.log(`stdout: ${stdout}`);
        });

# ...
  • 请确保您的应用程序至少有密码保护。docker.sock以任何方式曝光都是安全的事情。
  • 在这里您可以找到其他 Docker 客户端版本:https ://download.docker.com/linux/static/stable/x86_64/
  • 请替换<PART_OF_YOUR_CONTAINER_NAME>为您的容器名称的一部分。
于 2020-08-06T10:20:01.943 回答