运行时机
RUN在Dockerfile构建镜像的过程(Build)中运行,最终被commit的到镜像.
ENTRYPOINT和CMD在容器运行(run、start)时运行
都有shell和exec形式
shell形式
shell形式还有一个严重的问题:由于其默认使用/bin/sh来运行命令,如果镜像中不包含/bin/sh,容器会无法启动.
exec形式
CMD还多了一种用于为ENTRYPOINT提供参数的形式:
此时 ENTRYPOINT 必须使用 Exec 格式
参数格式
shell形式和exec的形式的本质区别在于shell形式提供了默认的指令/bin/sh -c,所以其指定的command将在shell的环境下运行.因此指定command的pid将不会是1,因为pid为1的是shell,command进程是shell的子进程.
exec形式则不然,但由于exec指定的命令不由shell启动,因此也就无法使用shell中的环境变量,如$HOME.如果希望能够使用环境变量,可以指定命令为sh:CMD [ “sh”, “-c”, “echo”, “$HOME” ]
重载问题
Dockerfile中只有最后一个ENTRYPOINT指令会生效,其他会被重载.
Dockerfile中只有最后一个CMD指令会生效,其他会被重载.
CMD指定的命令可以被docker run传递的命令覆盖.
ENTRYPOINT指定的命令不会被docker run传递的命令覆盖.容器名后面的所有内容都当成参数传递给其指定的命令.
当然,ENTRYPOINT指定的命令并不是不能重载的,只需指定–entrypoint来重载即可.
最佳实践
使用 RUN 指令安装应用和软件包,构建镜像.
如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令.CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数.
如果想为容器设置默认的启动命令,可使用 CMD 指令.用户可在 docker run 命令行中替换此默认命令.
ENTRYPOINT和CMD进行组合,运行shell脚本
1234567FROM busyboxMAINTAINER femnCOPY ./entrypoint.sh /RUN chmod +x /entrypoint.shENTRYPOINT ["/entrypoint.sh"]CMD ["echo","CMD"]
entrypoint.sh如下:
运行时则输出 ENTRYPOINT CMD,而运行的参数 都是传递给entrypoint.sh的.