Dockerfile中CMD和ENTRYPOINT的区别
在Dockerfile CMD是容器启动时运行的命令,ENTERPOINT作用和CMD是类似的,那么两者有何区别呢?先上结论:
CMD在运行docker run命令时容易被覆盖,而ENTERPOINT不容易被覆盖
下面通过示例演示下来看两者的区别?
Dockerfile
FROM alpine
CMD [ "/bin/echo","hello,world" ]
编译之后运行,结果如下:
# docker build -t test-cmd .
# docker run test-cmd
hello,world
换下运行命令再来看:
# docker run test-cmd /bin/echo hello,code
hello,code
可以看到后面的 /bin/echo hello,code
替换掉了 CMD 中指定的命令。
再来看ENTRYPOINT
Dockerfile
FROM alpine
ENTRYPOINT [ "/bin/echo","hello,world"]
编译之后运行,结果如下:
# docker build -t test-cmd .
# docker run test-cmd
hello,world
这里可以看到 CMD 和 ENTRYPOINT作用其实是一致的。
再将 CMD 和 ENTERYPOINT 组合在一起来看
Dockerfile
FROM alpine
ENTRYPOINT [ "/bin/echo"]
CMD [ "hello,world" ]
编译之后运行:
# docker build -t test-cmd .
# docker run test-cmd
hello,world
这里相当于运行了 /bin/echo hello,world
这个命令。
再次替换docker run的参数来看两者的区别:
# docker run test-cmd hello,code
hello,code
我们在docker run
后面添加了参数 hello,code
,相当于运行了 /bin/echo hello,code
,也就是用 hello,code
覆盖了CMD中的hello,world
参数。
其实ENTRYPOINT也可以在docker run中添加参数来指定,只不过麻烦点 要加 --entrypoint
还是上面的 Dockerfile
编译运行。在docker run
命令中用 /bin/ls
替换掉了 ENTRYPOINT
中的 /bin/echo
,用/bin/替换掉了 CMD
中的 hello,world
。
# docker build -t test-cmd .
# docker run --entrypoint="/bin/ls" test-cmd /bin/
arch
ash
base64
bbconfig
busybox
cat
chgrp
chmod
chown
conspy
cp
date
dd
df
...
总结
ENTRYPOINT
的目的和CMD
一样,都是在指定容器启动程序及参数。ENTRYPOINT
在运行时也可以替代,不过比CMD
要略显繁琐,需要通过docker run
的参数--entrypoint
来指定。
当指定了ENTRYPOINT
后,CMD
的含义就发生了改变,不再是直接的运行其命令,而是将CMD
的内容作为参数传给ENTRYPOINT
指令,换句话说实际执行时,将变为:
<ENTRYPOINT> "<CMD>"
这样做有什么好处呢?
- 通过将 ENTRYPOINT 和 CMD 组合起来就可以灵活地在docker run的时候指定需要的参数。
- 容器启动时可能需要做一些初始化的工作,那么可以在 ENTRYPOINT 来做这些事情(比如运行一个脚本来做初始化),用CMD来启动容器
- [1] <<第一本Docker书>>
- [2] <<Docker从入门到实践>>