为什么可以';我是否多次使用Docker CMD来运行多个服务?
我已经从Dockerfile构建了一个名为centos+ssh的基本映像。在centos+ssh的Dockerfile中,我使用CMD运行ssh服务 然后我想构建一个映像,运行另一个名为rabbitmq的服务,Dockerfile:为什么可以';我是否多次使用Docker CMD来运行多个服务?,docker,Docker,我已经从Dockerfile构建了一个名为centos+ssh的基本映像。在centos+ssh的Dockerfile中,我使用CMD运行ssh服务 然后我想构建一个映像,运行另一个名为rabbitmq的服务,Dockerfile: FROM centos+ssh EXPOSE 22 EXPOSE 4149 CMD /opt/mq/sbin/rabbitmq-server start 要启动rabbitmq容器,请运行: docker run -d -p 222:22 -p 4149:4149
FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD /opt/mq/sbin/rabbitmq-server start
要启动rabbitmq容器,请运行:
docker run -d -p 222:22 -p 4149:4149 rabbitmq
但ssh服务不起作用,它检测到rabbitmq的Dockerfile CMD覆盖了centos的CMD
没错,第二个Dockerfile将覆盖第一个Dockerfile的
CMD
命令。Docker将始终运行单个命令,而不是更多。因此,在Dockerfile的末尾,可以指定一个要运行的命令。不多了
但您可以在一行中执行这两个命令:
FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD service sshd start && /opt/mq/sbin/rabbitmq-server start
为了使Dockerfile更干净,您可以将CMD命令放在一个额外的文件中:
FROM centos+ssh
EXPOSE 22
EXPOSE 4149
CMD sh /home/centos/all_your_commands.sh
还有这样一个文件:
service sshd start &
/opt/mq/sbin/rabbitmq-server start
尽管CMD写在Dockerfile中,但它实际上是运行时信息。与暴露一样,但与运行和添加相反。我的意思是,您可以稍后在扩展Dockerfile中覆盖它,或者在run命令中覆盖它,这就是您正在经历的。在任何时候,都只能有一个CMD 如果您想运行多个服务,我确实会使用supervisor。您可以为每个服务创建一个管理器配置文件,将它们添加到一个目录中,并使用
supervisor-c/etc/supervisor
运行管理器,以指向一个管理器配置文件,该文件加载您的所有服务,看起来像
[supervisord]
nodaemon=true
[include]
files = /etc/supervisor/conf.d/*.conf
如果你想了解更多细节,我在这里写了一篇关于这个主题的博客:虽然我尊重qkrijger解释你如何解决这个问题的答案,但我认为我们可以了解更多关于这里发生的事情 真正回答你的问题“为什么”。。。我认为,了解
docker stop
命令的工作原理以及所有进程都应该干净地关闭,以防止在尝试重新启动时出现问题(文件损坏等),这将对您有所帮助
问题:如果docker确实从其命令启动了SSH,并从docker文件启动了RabbitMQ,该怎么办?“”docker跟踪作为PID 1的哪个进程将获得SIGTERM?是宋承宪还是兔子
答:Docker只需将最后一个CMD作为一个,它将作为根进程启动,PID为1,并从Docker stop
获取SIGTERM
建议的解决方案:您应该使用(或创建)一个专门用于运行多个服务的基本映像,例如
值得注意的是,正是出于这个原因,从Docker 1.13及更高版本开始,tini正式成为Docker的一部分,这告诉我们在Docker中运行多个进程是有效的。。因此,即使有人认为Docker是荒谬的,并且坚持认为你这样做是荒谬的,但要知道你不是。这样做是完全有道理的
很高兴知道:
- 码头工人的官方回答
它解释了如何使用init系统(systemd、sysvinit、upstart)、脚本(
CMD./my\u wrapper\u script.sh
)或类似于supervisord
的管理器来完成此操作
&&
解决方案只能用于在后台启动的服务(守护进程)或在没有交互和释放提示的情况下快速执行的服务。使用交互式服务(保持提示)执行此操作时,只有第一个服务将启动。要解决为什么CMD设计为每个容器只运行一个服务的问题,让我们了解一下,如果在同一容器中运行的辅助服务器不是琐碎的/辅助的,而是“主要的”(例如,与前端应用程序捆绑的存储). 首先,它将分解几个重要的容器化功能,例如水平(自动)扩展和节点之间的重新调度,这两个功能都假定每个容器只有一个应用程序(CPU负载源)。然后是漏洞的问题-容器中暴露的服务器越多,意味着CVE的修补就越频繁
因此,让我们承认,这是Docker(和Kubernetes/Openshift)设计师向良好实践的“推动”,我们不应该重新发明变通方法(SSH不是必需的-我们设计了Docker exec/kubectl exec/oc rsh
来取代它)
- 更多信息
谢谢,我想使用主管是很重要的 更好。但是为什么docker只运行一个CMD?里面发生了什么?我不知道里面发生了什么。但我认为它就是这样设计的。当您有一个图像并在其中运行命令(例如,使用CMD)时,它会启动一个容器。只要命令运行,容器就会一直运行。一旦命令完成,容器也会停止。所以每个容器代表一个(正在运行的)命令。我想可能是因为lcx或其他原因limit@Tyguy7 .. ................ ?
&&
技术只适用于非交互式服务(可以在后台启动),否则只有第一个服务会运行。谢谢,主管是个好主意,但我想知道CMD在docker Imager中是如何工作的。你问了两个问题,2。关于运行多个服务。想知道CMD是如何工作的,请详细说明你想知道的具体内容。我已经提到它是运行时信息,并且被任何新的CMD覆盖。