首页 > 解决方案 > 传递给 Kubernetes 作业和 Pod 的命令

问题描述

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

perl -Mbignum=bpi -wle '打印 bpi(2000)'

我已将命令传递给作业 yaml 文件,如下所示。通过 kubectl,yaml 文件成功创建作业并打印 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

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

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.

标签: kubernetesk8s-cronjobber

解决方案


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

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

---
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)'",但是这种语法没有任何意义,而且根本不正确。

你不妨问问为什么你不能跑'echo bla'进去bash,同时又echo bla跑成功,给你想要的结果。

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

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)"or"print", "bpi(2000)"perl -e只提供print没有任何意义的参数,因为它需要非常具体的命令来告诉它应该打印什么。就像您在 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)"] # 完整的单引号命令。

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中为 a定义 acommand和它的不同方法,我建议你阅读官方 kubernetes 文档中的这一部分。argumentscontainer


推荐阅读