您的当前位置:首页正文

docker的cmd命令详解-前后台理解

来源:帮我找美食网
docker的cmd命令详解-前后台理解

CMD 指令的格式和 RUN 相似,也是两种格式:

shell 格式:CMD <命令>

exec 格式:CMD [\"可执⾏⽂件\参数1\参数2\"...]

参数列表格式:CMD [\"参数1\参数2\"...]。在指定了 ENTRYPOINT 指令后,⽤ CMD 指定具体的参数。

之前介绍容器的时候曾经说过,Docker 不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,需要指定所运⾏的程序及参数。CMD 指令就是⽤于指定默认的容器主进程的启动命令的。

在运⾏时可以指定新的命令来替代镜像设置中的这个默认命令,⽐如,ubuntu 镜像默认的 CMD 是 /bin/bash,如果我们直接 docker run -it ubuntu的话,会直接进⼊ bash。我们也可以在运⾏时指定运⾏别的命令,如 docker run -it ubuntu cat /etc/os-release。这就是⽤ cat /etc/os-release 命令替换了默认的 /bin/bash 命令了,输出了系统版本信息。

在指令格式上,⼀般推荐使⽤ exec 格式,这类格式在解析时会被解析为 JSON 数组,因此⼀定要使⽤双引号 \",⽽不要使⽤单引号。如果使⽤ shell 格式的话,实际的命令会被包装为 sh -c 的参数的形式进⾏执⾏。⽐如:

CMD echo $HOME

在实际执⾏中,会将其变更为:

CMD [ \"sh\

这就是为什么我们可以使⽤环境变量的原因,因为这些环境变量会被 shell 进⾏解析处理。提到 CMD 就不得不提容器中应⽤在前台执⾏和后台执⾏的问题。这是初学者常出现的⼀个混淆。

Docker 不是虚拟机,容器中的应⽤都应该以前台执⾏,⽽不是像虚拟机、物理机⾥⾯那样,⽤ systemd 去启动后台服务,容器内没有后台服务的概念。

⼀些初学者将 CMD 写为:

CMD service nginx start

然后发现容器执⾏后就⽴即退出了。甚⾄在容器内去使⽤ systemctl 命令结果却发现根本执⾏不了。这就是因为没有搞明⽩前台、后台的概念,没有区分容器和虚拟机的差异,依旧在以传统虚拟机的⾓度去理解容器。

对于容器⽽⾔,其启动程序就是容器应⽤进程,容器就是为了主进程⽽存在的,主进程退出,容器就失去了存在的意义,从⽽退出,其它辅助进程不是它需要关⼼的东西。

⽽使⽤ service nginx start 命令,则是希望 upstart 来以后台守护进程形式启动 nginx 服务。⽽刚才说了 CMD service nginx start 会被理解为 CMD [\"sh\,因此主进程实际上是 sh。那么当 service nginx start 命令结束后,sh 也就结束了,sh 作为主进程退出了,⾃然就会令容器退出。

正确的做法是直接执⾏ nginx 可执⾏⽂件,并且要求以前台形式运⾏。⽐如:

CMD [\"nginx\

因篇幅问题不能全部显示,请点此查看更多更全内容

Top