是否可以从另一个容器启动已停止的容器
Is it possible to start a stopped container from another container
有两个容器A和B,一旦容器A启动,就会执行一个进程,然后容器就会停止。容器 B 只是一个 Web 应用程序(比如 expressjs)。是否可以从容器 B 启动 A?
可以授予容器对 docker 的访问权限,以便它可以在您的主机上生成其他容器。您可以通过在容器内公开 docker 套接字来实现此目的,例如:
docker run -v /var/run/docker.sock:/var/run/docker.sock --name containerB myimage ...
现在,如果容器内有可用的 docker
客户端,您将能够控制主机上的 docker 守护进程并使用它来生成“容器 A”。
在尝试此方法之前,您应该了解安全注意事项:访问 docker 与在主机上具有 root
访问权限相同,这意味着如果您的 Web 应用程序具有远程妥协,您刚刚将主机的密钥交给了攻击者。 in this article.
对此进行了更全面的描述
可以通过安装 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 作业等指定短期 "job" 服务的问题,但没有任何决定,更不用说编码了。因此,最好构建您的系统,以便容器启动并保持运行。
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>
替换为您容器名称的一部分。
有两个容器A和B,一旦容器A启动,就会执行一个进程,然后容器就会停止。容器 B 只是一个 Web 应用程序(比如 expressjs)。是否可以从容器 B 启动 A?
可以授予容器对 docker 的访问权限,以便它可以在您的主机上生成其他容器。您可以通过在容器内公开 docker 套接字来实现此目的,例如:
docker run -v /var/run/docker.sock:/var/run/docker.sock --name containerB myimage ...
现在,如果容器内有可用的 docker
客户端,您将能够控制主机上的 docker 守护进程并使用它来生成“容器 A”。
在尝试此方法之前,您应该了解安全注意事项:访问 docker 与在主机上具有 root
访问权限相同,这意味着如果您的 Web 应用程序具有远程妥协,您刚刚将主机的密钥交给了攻击者。 in this article.
可以通过安装 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 作业等指定短期 "job" 服务的问题,但没有任何决定,更不用说编码了。因此,最好构建您的系统,以便容器启动并保持运行。
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>
替换为您容器名称的一部分。