许吉友 - 运维

为容器设置启动时要执行的命令及其入参

文档地址:https://kubernetes.io/zh/docs/tasks/inject-data-application/define-command-argument-container/

创建 Pod 时,可以为其下的容器设置启动时要执行的命令及其入参。如果要设置命令,就填写在配置文件的 command 字段下,如果要设置命令的入参,就填写在配置文件的 args 字段下。一旦 Pod 创建完成,该命令及其入参就无法再进行更改了。

如果在配置文件中设置了容器启动时要执行的命令及其入参,那么容器镜像中自带的命令与入参将会被覆盖而不再执行。如果配置文件中只是设置了入参,却没有设置其对应的命令,那么容器镜像中自带的命令会使用该新入参作为其执行时的入参。

commands.yaml

apiVersion: v1
kind: Pod
metadata:
  name: command-demo
  labels:
    purpose: demonstrate-command
spec:
  containers:
  - name: command-demo-container
    image: debian
    command: ["printenv"]
    args: ["HOSTNAME", "KUBERNETES_PORT"]
  restartPolicy: OnFailure

运行:

$ kubectl apply -f commands.yaml
$ kubectl get pods
$ kubectl logs command-demo

使用环境变量来设置入参

在上面的示例中,我们直接将一串字符作为命令的入参。除此之外,我们还可以将环境变量作为命令的入参。

env:
- name: MESSAGE
  value: "hello world"
command: ["/bin/echo"]
args: ["$(MESSAGE)"]

这意味着你可以将那些用来设置环境变量的方法应用于设置命令的入参,其中包括了 ConfigMapsSecrets

注意: 环境变量需要加上括号,类似于 "$(VAR)"。这是在 commandargs 字段使用变量的格式要求。

通过 shell 来执行命令

有时候,您需要在 shell 脚本中运行命令。 例如,您要执行的命令可能由多个命令组合而成,或者它就是一个 shell 脚本。这时,就可以通过如下方式在 shell 中执行命令:

env:
  - name: MESSAGE
    value: "hello world"
command: ["/bin/sh"]
args: ["-c", "printenv HOSTNAME KUBERNETES_PORT MESSAGE \n while true; do echo hello; sleep 10;done"]

注意

下表给出了 Docker 与 Kubernetes 中对应的字段名称。

描述 Docker 字段名称 Kubernetes 字段名称
容器执行的命令 Entrypoint command
传给命令的参数 Cmd args

如果要覆盖默认的 Entrypoint 与 Cmd,需要遵循如下规则:

下表涵盖了各类设置场景:

镜像 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]