dockerCMD和ENTRYPOINT区别
昨天⽤Dockerfile来启动mongodb的集,启动参数--replSet死活没执⾏,最后就决定研究⼀哈cmd和entrypoint。但是上⽹看了⼀些资料个⼈觉得讲的不好,还是没有说出根本
的东西,决定⾃⼰研究并且整理⼀哈。
感觉官⽹关于这两个命令讲的简直不要太清楚。
cmd:
这个命令是⽤来做什么的?下⾯是官⽹的答案:
The main purpose of a CMD is to provide defaults for an executing container. These defaults can include an executable, or they can omit the executable, in which case you must specify an ENTRYPOINT instruction as well.意思是,cmd给出的是⼀个容器的默认的可执⾏体。也就是容器启动以后,默认的执⾏的命令。重点就是这个“默认”。意味着,如果docker run没有指定任何的执⾏命令或者dockerfile⾥⾯也没有entrypoint,那么,就会使⽤cmd指定的默认的执⾏命令执⾏。同时也从侧⾯说明了entrypoint的含义,它才是真正的容器启动以后要执⾏命令。
所以这句话就给出了cmd命令的⼀个⾓⾊定位,它主要作⽤是默认的容器启动执⾏命令。(注意不是“全部”作⽤)
这也是为什么⼤多数⽹上博客论坛说的“cmd会被覆盖”,其实为什么会覆盖?因为cmd的⾓⾊定位就是默认,如果你不额外指定,那么就执⾏cmd的命令,否则呢?只要你指定
了,那么就不会执⾏cmd,也就是cmd会被覆盖。
明⽩了cmd命令的主要⽤途。下⾯就看看具体⽤法。
总共有三种⽤法:
The CMD instruction has three forms:
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
因为还没有讲entrypoint,所以先不看⽤法2。
⽤法3:shell form,即没有中括号的形式。那么命令command默认是在“/bin/sh -c”下执⾏的。⽐如下⾯的dockerfile:
FROM centos
container容器用法
CMD echo "hello cmd!"
运⾏:
⽤法1:带有中括号的形式。这时,命令没有再任何shell终端环境下,如果我们要执⾏shell,必须把shell加⼊到中括号的参数中。这种⽤法就像⼀个c语⾔的exec函数,意思是
我们要执⾏⼀个进程。如果采⽤⾮shell的⽅法,那么上⾯的例⼦要修改为:
FROM centos
CMD ["/bin/bash", "-c", "echo 'hello cmd!'"]
需要注意,采⽤中括号形式,那么第⼀个参数必须是命令的全路径才⾏。⽽且,⼀个dockerfile⾄多只能有⼀个cmd,如果有多个,只有最后⼀个⽣效。
官⽹推荐采⽤这种⽅法。
当然,以上都是体现了cmd的“默认”⾏为。如果我们在run时指定了命令或者有entrypoint,那么cmd就会被覆盖。仍然是上⾯的image。run命令变了:
可以看到,最终容器⾥⾯执⾏的是run命令后⾯的命令,⽽不是cmd⾥⾯定义的。
接下来再看entrypoint:
An ENTRYPOINT allows you to configure a container that will run as an executable.
也就是说entrypoint才是正统地⽤于定义容器启动以后的执⾏体的,其实我们从名字也可以理解,这个是容器的“⼊⼝”。
有两种⽤法:
ENTRYPOINT has two forms:
ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)
ENTRYPOINT command param1 param2 (shell form)
命令⾏和shell。
先看命令⾏模式,也就是带中括号的。和cmd的中括号形式是⼀致的,但是这⾥貌似是在shell的环境下执⾏的,与cmd有区别。如果run命令后⾯有东西,那么后⾯的全部都会作
为entrypoint的参数。如果run后⾯没有额外的东西,但是cmd有,那么cmd的全部内容会作为entrypoint的参数,这同时是cmd的第⼆种⽤法。这也是⽹上说的entrypoint不会被覆
盖。当然如果要在run⾥⾯覆盖,也是有办法的,使⽤--entrypoint即可。
下⾯看⼏个例⼦。
dockerfile为:
FROM centos
CMD ["p in cmd"]
ENTRYPOINT ["echo"]
如果run不带参数:
如果run带参数:
⽽且,确实entrypoint的中括号形式下,command是在shell环境下运⾏的,否则这⾥的echo是⽆法被执⾏的。
第⼆种是shell模式的。在这种模式下,任何run和cmd的参数都⽆法被传⼊到entrypoint⾥。官⽹推荐第⼀种⽤法。
FROM centos
CMD ["p in cmd"]
ENTRYPOINT echo
cmd的参数没有被打印。
总结下⼀般该怎么使⽤:⼀般还是会⽤entrypoint的中括号形式作为docker 容器启动以后的默认执⾏命令,⾥⾯放的是不变的部分,可变部分⽐如命令参数可以使⽤cmd的形式提供默认版本,也就是run⾥⾯没有任何参数时使⽤的默认参数。如果我们想⽤默认参数,就直接run,否则想⽤其他参数,就run ⾥⾯加参数

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。