什么是容器启动命令
在创建 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。