什么是容器启动命令
在创建 POD 时,我们可以为容器指定需要执行的启动命令以及参数。如果要设置命令,就填写在配置文件的 command 字段下,如果要设置命令的参数,就填写在配置文件的 args 字段下。 一旦 Pod 创建完成,该命令及其参数就无法再进行更改了。
对于 Kubernetes 而言,配置文件中的 command
和 args
分别对应的是 Dockerfile 中的 ENTRYPOINT
和 CMD
命令。
这意味着当你在 Kubernetes Pod 中指定 command
时,它会覆盖 Docker 镜像中定义的 ENTRYPOINT
。同样,当你指定 args
时,它会覆盖 Docker 镜像中定义的 CMD
。但会有一些特殊情况,比如只指定配置 command
的时候,只指定配置 args
的时候,下面会对这些情况进行详细说明
在了解这几个特殊情况之前,我们先来了解下 Dockerfile 中的 ENTRYPOINT
和 CMD
。
对于 Dockerfile 中的 ENTRYPOINT
和 CMD
容器应用进程 = ENTRYPOINT
+ CMD
。
ENTRYPOINT
定义了容器启动时运行的命令。它可以是一个可执行文件或者一个脚本,例如 nginx 容器的 Dockerfile下的 ENTRYPOINT
为 /docker-entrypoint.sh
。如果在 Dockerfile 中没有显式配置 ENTRYPOINT
,Docker 会使用一个默认的 ENTRYPOINT
。这个默认的 ENTRYPOINT
是 /bin/sh -c
。
需要注意的是当一个 Dockerfile 中同时存在多条 ENTRYPOINT
时,只有最后一条ENTRYPOINT
会生效。
CMD
定义了容器启动时运行的命令的参数。CMD
提供了 ENTRYPOINT
的默认参数。如果没有提供 CMD
,那么 ENTRYPOINT
需要是一个完整的命令。如果提供了 CMD
,它可以作为 ENTRYPOINT
的参数。反之如果没有 ENTRYPOINT
,则 CMD
需要是一个完整命令。
使用的几种情况
- 替换而非追加:在 Kubernetes 中,当你设置
command
或args
时,你是在替换Docker
镜像中的ENTRYPOINT
和CMD
,而不是在它们后面追加命令或参数。 - 只设置
command
:当设置command
时,Docker
镜像中的ENTRYPOINT
将被替换,而CMD
将被忽略。 - 只设置
args
:当设置args
时,Docker
镜像中的CMD
将被替换,而ENTRYPOINT
将被忽略。
k8s pod | docker | 最后生效的命令 | ||
---|---|---|---|---|
command | args | entrypoint | cmd | |
配置 | 配置 | 配置 | 配置 | entrypoint+args |
配置 | 不配置 | 配置 | 配置 | command |
不配置 | 配置 | 配置 | 配置 | entrypoint+args |
不配置 | 不配置 | 配置 | 配置 | entrypoint+cmd |
不配置 | 配置 | 不配置 | 配置 | args |
不配置 | 配置 | 配置 | 不配置 | entrypoint+args |
总而言之 Kubernetes 中的
command
对应于 Docker 的ENTRYPOINT
,而args
对应于 Docker 的CMD
,并且在 Kubernetes Pod 定义中指定这些会覆盖 Docker 镜像中的相应设置。
示例
有一个 例如 Bash 镜像 ,它有一个 ENTRYPOINT
和 CMD
,如下所示:
|
|
在这个 Dockerfile ,默认的ENTRYPOINT
是docker-entrypoint.sh
,而bash
是传递给它的默认CMD
。
只设置 command
,不设置 args
Kubernetes Pod 的配置如下:
|
|
可以看到输出:
|
|
即所执行的命令为 bash -c echo hello bash
(Kubernetes yaml 中的 command
+ Dockerfile 中的 CMD
)。
只设置 args
,不设置 command
Kubernetes Pod 的配置如下:
|
|
可以看到输出:
|
|
即所执行的命令为 docker-entrypoint.sh python3 --version
(Dockerfile 中的 ENTRYPOINT
+ Kubernetes yaml 中的 args
)。
设置 command
和 args
Kubernetes Pod 的配置如下:
|
|
可以看到输出:
|
|
即所执行的命令为 bash -c echo hello
(Kubernetes yaml 中的 command
+ Kubernetes yaml 中的 args
)。
不设置 command
和 args
即直接运行 Docker 镜像中的 ENTRYPOINT
和 CMD
。