目录
DockerFile
CMD
ENTRYPOINT
CMD 与 ENTRYPOINT 优先级
CMD 与 ENTRYPOINT 使用建议:
创建 Pod 时设置命令及入参
通过 shell 来执行命令
Docker 与 Kubernetes 的对应关系
CMD指令在Dockerfile中仅允许一条,若出现多条,那么都会被最后一条CMD 指令覆盖掉
CMD指令主要是为容器运行时提供默认值,这些默认值可以有执行命令操作,也可以只有参数配置,这需要与ENTRYPOINT结合使用
CMD指令有着三种配置形式
CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;
CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;
CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;
CMD 示例:
CMD ["/usr/bin/wc","--help"]
CMD echo "This is a test." | wc -
ENTRYPOINT :配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。每个Dockerfile中只能有一个 ENTRYPOINT ,当指定多个时,只有最后一个起效
ENTRYPOINT指令配置形式
ENTRYPOINT ["executable", "param1", "param2"] (exec 形式, 推荐)
ENTRYPOINT command param1 param2 (shell 形式)
shell形式防止使用任何CMD或者运行命令行参数,但是缺点是ENTRYPOINT将作为/bin/sh -c的子命令启动,不传递信号。这意味着可执行文件将不是容器的PID 1,并且不接收Unix信号,因此您的可执行文件将不会从docker stop
ENTRYPOINT 示例
ENTRYPOINT ["top", "-b"]
ENTRYPOINT exec top -b
- Dockerfile应该指定至少一个CMD或ENTRYPOINT命令。
- 在将容器用作可执行文件时,应该定义ENTRYPOINT。
- CMD应该用作定义ENTRYPOINT命令的默认参数或在容器中执行特别命令的方法。
- 当运行带有可选参数的容器时,CMD将被覆盖。
|
No ENTRYPOINT |
ENTRYPOINT exec_entry p1_entry (shell 形式) |
ENTRYPOINT [“exec_entry”, “p1_entry”] (exec 形式) |
NO CMD |
不允许 |
/bin/sh -c exec_entry p1_entry |
exec_entry p1_entry |
CMD [“exec_cmd”, “p1_cmd”] (exec 形式) |
exec_cmd p1_cmd |
/bin/sh -c exec_entry p1_entry |
exec_entry p1_entry exec_cmd p1_cmd |
CMD [“p1_cmd”, “p2_cmd”] (参数 形式) |
p1_cmd p2_cmd |
/bin/sh -c exec_entry p1_entry |
exec_entry p1_entry p1_cmd p2_cmd |
CMD exec_cmd p1_cmd (shell 形式) |
/bin/sh -c exec_cmd p1_cmd |
/bin/sh -c exec_entry p1_entr |
exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd |
(1)CMD命令用来执行image中的所有应用。CMD一般采用CMD [“executable”, “param1”, “param2”…]的格式来运行。所以,如果你的image是用来提供服务的,例如Apache,Rails。你就应该执行类似这样的命令CMD ["apache2","-DFOREGROUND"]。
(2)在其他的case中,CMD用来执行特定的shell,比如:bash,python,perl等等。比如: CMD ["perl", "-de0"] , CMD ["python"] , or CMD [“php”, “-a”]。
(3)当你执行docker run -it python时就可以进入特定的shell中。
(4)CMD经常是配合 ENTRYPOINT 来使用的。除非确定你的用户非常了解ENTRYPOINT 的特性。否则还是建议你事先设定好ENTRYPOINT
创建 Pod 时,可以为其下的容器设置启动时要执行的命令及其入参。如果要设置命令,就填写在配置文件的 command
字段下,如果要设置命令的入参,就填写在配置文件的 args
字段下。一旦 Pod 创建完成,该命令及其入参就无法再进行更改了。
- 如果在配置文件中设置了容器启动时要执行的命令及其入参,那么容器镜像中自带的命令与入参将会被覆盖而不再执行。
- 如果配置文件中只是设置了入参,却没有设置其对应的命令,那么容器镜像中自带的命令会使用该新入参作为其执行时的入参。
有时候,您需要在 shell 脚本中运行命令。 例如,您要执行的命令可能由多个命令组合而成,或者它就是一个 shell 脚本。这时,就可以通过如下方式在 shell 中执行命令:
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
描述 | Docker 字段名称 | Kubernetes 字段名称 |
---|---|---|
容器执行的命令 | Entrypoint | command |
传给命令的参数 | Cmd | args |
如果要覆盖默认的 Entrypoint 与 Cmd,需要遵循如下规则:
如果在容器配置中没有设置
command
或者args
,那么将使用 Docker 镜像自带的命令及其入参。如果在容器配置中只设置了
command
但是没有设置args
,那么容器启动时只会执行该命令,Docker 镜像中自带的命令及其入参会被忽略。如果在容器配置中只设置了
args
,那么 Docker 镜像中自带的命令会使用该新入参作为其执行时的入参。如果在容器配置中同时设置了
command
与args
,那么 Docker 镜像中自带的命令及其入参会被忽略。容器启动时只会执行配置中设置的命令,并使用配置中设置的入参作为命令的入参。
下表涵盖了各类设置场景:
镜像 Entrypoint | 镜像 Cmd | 容器 command | 容器 args | 命令执行 |
---|---|---|---|---|
[/ep-1] |
[foo bar] |
[ep-1 foo bar] |
||
[/ep-1] |
[foo bar] |
[/ep-2] |
[ep-2] |
|
[/ep-1] |
[foo bar] |
[zoo boo] |
[ep-1 zoo boo] |
|
[/ep-1] |
[foo bar] |
[/ep-2] |
[zoo boo] |
[ep-2 zoo boo] |
参考链接:
https://kubernetes.io/zh/docs/tasks/inject-data-application/define-command-argument-container/#%E6%B3%A8%E6%84%8F