docker容器中的EntryPoint和CMD命令区别

entrypoint设置容器的入口程序,就是容器启动时执行的程序,docker run中最后的命令将作为参数传给入口程序,它有两种格式exec和shell,它们之间区别在于指定的命令是否在shell中运行,其中shell底层使用/bin/sh -c COMMAND运行,就是说主进程shell进程,后面正在执行命令的进程是在shell进程中启动,这时shell进程往往是多余的,因此通常采用exec形式ENTRYPOINT指令,格式如下:

Shell 格式

<instruction> <command>

示例如下:

ENTRYPOINT echo "Hello, $name" 

将输出:

Hello, Cloud Man

此时入口程序不能接受信号量,也就是忽略docker run的参数和cmd指令的参数,如果有多个entrypoint,只有最后一个生效。run是编译镜像时执行的脚本和程序,编译完成run指令生命周期结束,一般用shell命令。而cmd和entrypoint一般用exec指令,格式如下

Exec 格式

<instruction> ["executable", "param1", "param2", ...]

示例比如

CMD ["java","-jar","/root/a.jar","/root/aa.json"]//这个是exec

如果同时出现cmd和entrypoint,cmd作为参数传递给entrypoint指令。

ENTRYPOINT ["/bin/echo", "Hello, $name"]

运行容器将输出:

Hello, $name

注意环境变量“name”没有被替换。
如果希望使用环境变量,照如下修改

ENV name Cloud Man  

ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"]

Dockerfile中ENTRYPOINT和CMD的区别

Dockerfile中,环境参数写在ENTRYPOINT和CMD是有区别的

写在ENTRYPOINT中,其效果是追加的方式,

写在CMD中,其效果是覆盖的方式,

理解起来很困难,下面通过实例来解析这个区别

假如项目的application.yml的默认配置为spring.profiles.active=native

如Dockerfile文件如下:

FROM java:8
# ARG JAR_FILE
# ARG LIB_FILE
VOLUME /tmp
ADD lib lib
ADD config-center-1.0.jar /app.jar
# ADD ${LIB_FILE} /lib
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-Duser.timezone=GMT+08","-Dspring.profiles.active=dev","-Deureka.instance.ipAddress=172.16.11.76","-Dserver.port=8889"]
CMD ["-Xms512m","-Xmx512m","-jar", "/app.jar"]
参数是写在ENTRYPOINT的,其运行效果就是追加的方式,效果为spring.profiles.active=dev,native,这样两个环境参数都激活了

若修改为:

FROM java:8
# ARG JAR_FILE
# ARG LIB_FILE
VOLUME /tmp
ADD lib lib
ADD config-center-1.0.jar /app.jar
# ADD ${LIB_FILE} /lib
CMD ["java","-Djava.security.egd=file:/dev/./urandom","-Duser.timezone=GMT+08","-Dspring.profiles.active=dev","-Deureka.instance.ipAddress=172.16.11.76","-Dserver.port=8889","-Xms512m","-Xmx512m","-jar", "/app.jar"]
参数写在CMD中,所有参数是覆盖的效果,效果为spring.profiles.active=dev

 

posted @ 2020-06-07 13:28  ppjj  阅读(1301)  评论(0编辑  收藏  举报