博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

docker cmd

Posted on 2018-03-13 18:00  bw_0927  阅读(1007)  评论(0)    收藏  举报

 

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

  • shell 格式:CMD <命令>
  • exec 格式:CMD ["可执行文件", "参数1", "参数2"...]       #方括号

Docker 不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,需要指定所运行的程序及参数。CMD 指令就是用于指定默认的容器主进程的启动命令的。

例子:
#Dockfile 
FROM centos:centos6
CMD echo $HOME

生成image:
docker build -t dockfile:test_cmd .


测试image(不带命令):
docker run dockfile:test_cmd

输出:
/root

测试image(带命令):
docker run dockerfile:test echo "hi"

输出:
hi

  

 

CMD echo $HOME

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

CMD [ "sh", "-c", "echo $HOME" ]

bash -c string If the -c option is present, then commands are read from string.

这就是为什么我们可以使用环境变量的原因,因为这些环境变量会被 shell 进行解析处理。

 

在运行时可以指定新的命令来替代镜像设置中的这个默认命令,比如,ubuntu 镜像默认的 CMD 是 /bin/bash,如果我们直接 docker run -it ubuntu 的话,会直接进入 bash

我们也可以在运行时指定运行别的命令,如 docker run -it ubuntu cat /etc/os-release

 

Docker 不是虚拟机,容器就是进程

Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 upstart/systemd 去启动后台服务,容器内没有后台服务的概念。

一些初学者将 CMD 写为:

CMD service nginx start

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

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

而使用 service nginx start 命令,则是希望 upstart 来以后台守护进程形式启动 nginx 服务。而刚才说了 CMD service nginx start 会被理解为 CMD [ "sh", "-c", "service nginx start"],因此主进程实际上是 sh

那么当 service nginx start 命令结束后,sh 也就结束了,sh 作为主进程退出了,自然就会令容器退出。

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

CMD ["nginx", "-g", "daemon off;"]           方括号

 nginx -g directives : set global directives out of configuration file

 

 

 

=====================

FROM centos:centos6
#xxx
CMD ["/bin/bash"]

即使Dockerfile里面的CMD写的是/bin/bash,

但如果 docker run  centos:v1  ,也是不会进入shell的

你需要docker run  -it centos:v1  才行

 

docker run :创建一个新的容器并运行一个命令

docker create :创建一个新的容器但不启动它

docker exec :在运行的容器中执行命令