传递给 Kubernetes 作业和 Pod 的命令

Commands passed to a Kubernetes Job and Pod

我有一个 perl 命令需要传递给 kubernetes 作业。命令计算 pi 的值并将其打印到 2000 位。

perl -Mbignum=bpi -wle 'print bpi(2000)'

我已将命令传递给作业 yaml 文件,如下所示。通过kubectl,yaml文件成功创建job,并打印出pi的值。

apiVersion: batch/v1
kind: Job
metadata:
   name: pi-job
spec:
   template:
     spec:
        containers:
          - name: pi
            image: perl
            command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
        restartPolicy: Never

当我尝试使用以下命令语法时,出现错误。你能告诉我为什么下面的命令 synax 不正确吗?

command: ["perl",  "-Mbignum=bpi", "-wle", "'print bpi(2000)'"]     # placed inside single quote
command: ["perl",  "-Mbignum=bpi", "-wle", "print", " bpi(2000)"]   # print splitted in two quotes.
command: ["perl",  "-Mbignum=bpi", "-wle", "print", "bpi(2000)"]    # print splitted in two quotes.

另外,当我在单引号中传递完整的命令时,它会报错。

command: ["perl -Mbignum=bpi -wle print bpi(2000)"]       # complete command in single quotes.

command: 键要求您传递 数组 作为参数(与 this 示例比较)。您可以用两种等效形式指定一个数组:

在一行中,使用方括号 []:

---
items: [ 1, 2, 3, 4, 5 ]
names: [ "one", "two", "three", "four" ]

并以多行方式:

---
items:
  - 1 
  - 2 
  - 3
  - 4 
  - 5 
names:
  - "one"
  - "two"
  - "three"
  - "four"

您可以同时使用双 " 和单引号 ' 引号,因此下面的示例也是正确的并且可以工作:

command: ['perl',  '-Mbignum=bpi', '-wle', 'print bpi(2000)']

但是您不能同时使用两者。我不知道你想通过 "'print bpi(2000)'" 实现什么,但这种语法没有任何意义,而且根本不正确。

你不妨问为什么不能在bash中运行'echo bla'同时echo bla运行s成功,给出你想要的结果。

请注意,在 kubernetes 中以这种方式提供 command 时,只有数组的第一个元素是实际的 command(在 $PATH) 和其他后续元素是它的参数。牢记这一点,您应该注意到接下来的两个示例也没有任何意义,因为单独提供的 "print" 和 "bpi(2000)" 都不是有效参数:

command: ["perl",  "-Mbignum=bpi", "-wle", "print", " bpi(2000)"]   # print splitted in two quotes.
command: ["perl",  "-Mbignum=bpi", "-wle", "print", "bpi(2000)"]    # print splitted in two quotes.

为了能够完全理解此命令的作用,我们需要深入研究基本的 perl 文档。我只留下了在我们的示例中使用并与之相关的那些选项:

$ perl --help

Usage: perl [switches] [--] [programfile] [arguments]
  -e program        one line of program (several -e's allowed, omit programfile)
  -l[octal]         enable line ending processing, specifies line terminator
  -[mM][-]module    execute "use/no module..." before executing program
  -w                enable many useful warnings

Run 'perldoc perl' for more help with Perl.

现在让我们一步步分析我们的命令:

["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]

主命令"perl"后面的数组的每个元素都是一个单独的实体,作为主命令的参数传递它的标志,或最近提供的标志的参数,根据文档,它是必需的,应该以非常具体的形式提供。

在我们的 -wle 标志集中,e 选项至关重要,因为它后面必须跟有特定参数:

 -e program        one line of program (several -e's allowed, omit programfile)

在我们的示例中是:

print bpi(2000)

我要再强调一遍。数组的每个元素都被视为一个单独的实体。通过将它分成两个单独的元素,例如 "print", " bpi(2000)""print", "bpi(2000)" 你只用 perl -e 参数提供 perl -e 这没有任何意义,因为它需要非常具体的命令告诉它应该打印什么。就好像你 运行 in bash shell:

perl -Mbignum=bpi -wle 'print' 'bpi(2000)'

这将导致 perl 解释器出现以下错误:

Use of uninitialized value $_ in print at -e line 1.

最后当你 运行 你的最后一个例子:

command: ["perl -Mbignum=bpi -wle print bpi(2000)"] # complete command in single quotes.

您会收到非常详细的消息,解释为什么它在 Pod 事件 (kubectl describe pod pi) 中不起作用:

Error: failed to start container "pi": Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"perl -Mbignum=bpi -wle print bpi(2000)\": executable file not found in $PATH": unknown

它基本上试图在 $PATH 中找到一个名为 "perl -Mbignum=bpi -wle print bpi(2000)" 的可执行文件,这当然是不可能的。

如果您想熟悉在 kubernetes 中为 container 定义 command 及其 arguments 的不同方式,我建议您正在阅读官方 kubernetes 文档中的 this 部分。