我需要解决同样的问题。在我的情况下,一切都始于我需要通过cron运行位于另一个容器中的一些脚本,我尝试了以下场景但没有成功:
忘记两个容器的场景,将所有逻辑放在一个容器中,因此不再需要容器间执行:结果证明这是一个坏主意,因为整个Docker概念是在每个容器中执行单个任务。无论如何,创建一个dockerfile来构建一个带有我的主要服务(在我的情况下是PHP)和cron守护程序的镜像证明是相当混乱的。
通过SSH在容器之间通信:然后我决定尝试构建一个图像,该图像将负责运行Cron守护程序,这将是“docker”解决我的问题的方法,但是不好的想法是通过打开到另一个容器的SSH连接(在您的情况下,C1通过SSH连接到C2)来执行每个cronjob的命令。事实证明,实现容器间的SSH登录非常笨拙,并且我一直遇到权限、无密码登录和端口路由问题。最终它起作用了,但我确定这会增加一些潜在的安全问题,而且我觉得这不是一个干净的解决方案。
实现某种API,我可以通过HTTP请求从一个容器调用另一个容器,使用类似Curl或Wget的东西。这感觉像是一个很好的解决方案,但最终意味着将第二个服务添加到我的容器中(一个Nginx用于处理HTTP连接),并处理HTTP要求和超时只是为了执行一个shell脚本感觉太麻烦了。
最终,我的解决方案是从容器内部运行“docker exec”。正如scnerd所描述的那样,这个想法是确保Docker客户端与主机上的Docker服务进行交互:
为此,您必须将Docker安装到要执行命令的容器中(在您的情况下是C1),通过向Dockerfile(对于Debian)添加类似以下的一行:
RUN apt-get update && apt-get -y install docker.io
为了让容器内部的Docker客户端与主机上的Docker服务进行交互,您需要将/var/run/docker.sock作为一个卷添加到容器(C1)中。使用Docker Compose可以通过将以下内容添加到Docker服务的"volumes"部分来完成这一操作:
- /var/run/docker.sock:/var/run/docker.sock
现在,当您构建和运行Docker镜像时,您将能够从Docker内部执行"docker exec"命令,使用类似于这样的命令,并与主机上的Docker服务通信:
docker exec -u root C2 /path/your_shell_script
这对我很有帮助。由于在我的情况下,我希望Cron容器可以启动其他容器中的脚本,所以只需将“docker exec”命令添加到crontab即可。
这个解决方案,就像scnerd提出的一样,可能不是最优的,我同意他关于你的结构的评论:考虑到你的特定需求,这可能不是你需要的,但应该能够工作。
我很想听听比我更有Docker经验的人的任何意见!