区分Dockerfile的ENTRYPOINT和CMD命令

Dockerfile的命令中包含ENTRYPOINT和CMD,使用ENTRYPOINT或者CMD,都可以达到让容器run起来的目的,但他们之间如何区分和选择呢?

CMD

CMD命令是一个容器的默认可执行体,也就是说容器启动之后默认会执行CMD的命令。我们在使用docker run时如果没有指定任何可执行命令并且Dockerfile里面业没有ENTRYPOINT,那么就会使用CMD指定的命令作为默认执行命令。

CMD有以下三种使用凡事

  1. 作为默认的执行命令的形式
CMD ["program", "arg1", "arg2", ...]

带有中括号的形式。这时,命令没有再任何shell终端环境下,如果我们要执行shell,必须把shell加入到中括号的参数中。这种用法就像一个c语言的exec函数,意思是我们要执行一个进程。如果采用非shell的方法,那么上面的例子要修改为:

FROM centos

CMD ["/bin/bash", "-c", "echo 'Hello Docker CMD!'"]

该种形式需要注意,在指定可执行程序时,需要指定全路径,而且一个Dockerfile中最多只能有一个CMD命令,如果写了多个,只有最后一个会生效。

  1. 作为默认的执行命令的另一种形式
CMD command arg1 arg2 ...

如果是这种形式,则不需要将bash显示指定,例如:

FROM centos

CMD echo 'Hello Docker CMD!'
  1. 为ENTRYPOINT提供执行参数
CMD ["args1", "arg2", ...]

CMD命令的行为在使用docker run命令的时候可以指定执行的命令去覆盖它,例如:

docker run xxx echo 'hello docker!'

ENTRYPOINT

ENTRYPONT是容器启动以后的真正的执行体,这也是官方推荐的使用方式。它有两种使用表现形式

ENTRYPOINT ["program", "arg1", "arg2", ...]

ENTRYPOINT command arg1 arg2 ...

使用第一种带括号的方式

这种方式可以结合CMD的第三种方式使用,例子如下:

FROM centos

CMD ["cmd args"]

ENTRYPOINT ["echo"]

在运行该Dockerfile生成的image时,如果docker run不指定参数,则会打印出cmd args,如果docker run指定了参数,则会打印出指定的参数

使用第二种不带括号的方式

这种方式会直接指定死执行的命令和参数,无法在后期通过docker run修改,同时它无法与CMD混合使用,例如

FROM centos

CMD ["xxx"]

ENTRYPOINT echo

运行该Dockerfile生成的image,则不会打印出任何东西,即使在docker run显示指定参数也不会被打印出来。

总结

ENTRYPOINT + CMD 组成Docker容器的命令,分别使用ENTRYPOINT的第一种方式和CMD的第三种方式组合使用为最佳实践,当docker run不指定参数时使用CMD指定的参数(默认参数),当指定参数时,使用指定的参数。

注:ENTRPOINT也是可以在运行时被重置的,使用docker run--entrypoint参数即可

你可能感兴趣的:(Docker)