Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以从另一个容器在Docker容器内运行命令?_Docker - Fatal编程技术网

是否可以从另一个容器在Docker容器内运行命令?

是否可以从另一个容器在Docker容器内运行命令?,docker,Docker,这是我的设想 我有2个Docker容器: C1:是一个带有Ruby(但也可以是其他任何东西)的容器,它准备数据文件,必须在这些文件上用Julia语言执行计算 C2:是一个带有Julia(或R,或倍频程…)的容器,用于执行计算,以避免在运行Ruby代码的同一系统或容器上安装Julia 从主机上看,显然,我在处理方面没有问题。 通常,当两个容器链接(或属于同一网络)时,它们通过一个网络相互通信,从而打开一些门。在这种情况下,Julia不会打开任何门 我可以从C1在C2上运行类似于主机和C2之间的

这是我的设想

我有2个Docker容器:

  • C1:是一个带有Ruby(但也可以是其他任何东西)的容器,它准备数据文件,必须在这些文件上用Julia语言执行计算
  • C2:是一个带有Julia(或R,或倍频程…)的容器,用于执行计算,以避免在运行Ruby代码的同一系统或容器上安装Julia
从主机上看,显然,我在处理方面没有问题。 通常,当两个容器链接(或属于同一网络)时,它们通过一个网络相互通信,从而打开一些门。在这种情况下,Julia不会打开任何门

我可以从C1在C2上运行类似于主机和C2之间的命令吗? 如果是,怎么做


谢谢

技术上是的,但这可能不是你想要做的

Docker CLI只是Docker服务的一个接口,它在主机上侦听/var/run/Docker.sock。可以通过CLI执行的任何操作都可以通过直接与此服务器通信来完成。您可以将此套接字作为卷装入正在运行的容器(C1),以允许该容器与其主机的docker服务对话。Docker有一些权限需要设置以允许此操作;旧版本允许容器在“特权”模式下运行,在这种情况下,允许容器(除其他外)在主机的授权下与/var/run/docker.sock对话。我相信Docker的新版本将这个权限系统拆分了一点,但你必须对此进行研究。在swarm模式下实现这一点也可能有点不同。在代码级别使用此API而不在容器中安装完整的Docker CLI当然是可能的(或者编写自己的交互代码)。JupyterHub+DockerSpawner就是这样一个工作的例子,它有一个特权中心服务器,为每个登录用户实例化新的笔记本容器


我刚刚看到您明确声明Julia容器没有门/接口。您能否将代码包装在一个更大的容器中,为其提供一个服务器接口,同时将无服务器Julia程序作为同一容器中的“本地”进程进行管理?

我需要解决同样的问题。在我的例子中,当我需要通过cron运行位于另一个容器中的一些脚本时,一切都开始了,我尝试了以下场景,但没有成功:

  • 忘记两个容器场景,将所有逻辑放在一个容器中,因此不再需要容器间执行:这是一个坏主意,因为整个Docker概念是在每个容器中执行单个任务。在任何情况下,创建一个dockerfile来构建一个包含我的主服务(在我的例子中是PHP)和一个cron守护进程的映像都是非常混乱的

  • 通过SSH在容器之间通信:然后我决定尝试构建一个映像,负责运行Cron守护进程,这是解决我的问题的“docker”方法,但坏主意是通过打开到另一个容器的SSH连接来执行来自每个cronjob的命令(在您的例子中,C1通过SSH连接到C2)。事实证明,实现容器间SSH登录非常笨拙,并且我一直遇到权限、无密码登录和端口路由问题。最终它成功了,但我相信这会增加一些潜在的安全问题,我觉得这不是一个干净的解决方案

  • 实现某种API,我可以使用Curl或Wget之类的东西通过HTTP请求从一个容器调用到另一个容器。这感觉是一个很好的解决方案,但最终意味着向我的容器添加一个辅助服务(一个参与HTTP连接的Nginx),而仅仅为了执行shell脚本而处理HTTP请求和超时感觉太麻烦了

最后,我的解决方案是从容器中运行“docker exec”。这样做的目的是确保docker客户端与主机中的docker服务交互:

为此,您必须将docker安装到要从中执行命令的容器中(在您的示例中为C1),方法是在Dockerfile(对于Debian)中添加一行,如下所示:

要使容器内的docker客户端与主机上的docker服务交互,您需要将/var/run/docker.sock作为卷添加到容器(C1)中。使用docker compose,可以通过将其添加到docker服务“卷”部分来完成此操作:

现在,当您构建并运行docker映像时,您将能够使用如下命令从docker中执行“docker exec”,并且您将与主机上的docker服务对话:

docker exec -u root C2 /path/your_shell_script
这对我来说效果很好,因为在我的例子中,我希望Cron容器在其他容器中启动脚本,所以只需向crontab添加“docker exec”命令即可

这个解决方案也可能不是最优的,我同意他对你的结构的评论:考虑到你的具体需求,这可能不是你所需要的,但它应该是有效的


我希望听到比我更熟悉Docker的人的评论!

这两个容器是否在同一个专用网络中?如果是,您是否尝试过访问另一个容器(ping、ssh)?
- /var/run/docker.sock:/var/run/docker.sock
docker exec -u root C2 /path/your_shell_script