Команды, переданные Kubernetes Job и Pod - PullRequest
1 голос
/ 04 февраля 2020

У меня есть команда perl, которую мне нужно передать на работу в kubernetes. Команда вычисляет и печатает значение pi до 2000 мест.

perl -Mbignum = bpi -wle 'print 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

Когда я пробовал с приведенным ниже синтаксисом команды, это выдает мне ошибку. Скажите, пожалуйста, почему приведенная ниже команда 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.

1 Ответ

1 голос
/ 04 февраля 2020

command: ключ требует, чтобы вы передали массив в качестве аргумента (сравните с этим примером). Вы можете указать массив в двух эквивалентных формах:

в одну строку, используя квадратные скобки []:

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

и многострочно :

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

Вы можете использовать как двойные ", так и signle ' кавычки, поэтому приведенный ниже пример также будет верным и будет работать:

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

Однако вы не можете использовать оба одновременно. Я не знаю, чего бы вы хотели достичь, поставив "'print bpi(2000)'", но этот синтаксис не имеет никакого смысла и просто неверен.

Вы также можете спросить, почему вы не можете запустить 'echo bla' в bash, в то же время echo bla работает успешно, давая вам желаемый результат.

Обратите внимание, что при предоставлении command таким образом в kubernetes , только первый элемент массива является действительным 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.

Чтобы полностью понять, что делает эта команда, нам нужно немного углубиться в основную документацию c 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" является отдельной сущностью, которая передается как аргумент основной команды , ее флаг или аргумент недавно предоставленного флага , который в соответствии с документацией требуется и должен быть предоставлен в очень конкретной форме c.

В нашем наборе -wle флагов опция e имеет решающее значение, так как за ней следует указывать c аргумент:

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

, который в нашем примере:

print bpi(2000)

Я хочу подчеркнуть это еще раз. Каждый элемент массива рассматривается как отдельный объект. Разбивая его на два отдельных элемента, таких как "print", " bpi(2000)" или "print", "bpi(2000)", вы кормите perl -e только аргументом print, который не имеет никакого смысла, так как требует очень конкретной команды c, сообщающей, что должно быть распечатаны. Это так же, как если бы вы запускали в bash shell:

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

, что приведет к следующей ошибке интерпретатора perl:

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

И, наконец, когда вы запустите последний пример:

команда: ["perl -Mbignum = bpi -wle print bpi (2000)"] # полная команда в одинарных кавычках.

you ' я получу довольно подробное сообщение, объясняющее, почему оно не работает в 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)", который, конечно, не может быть сделано.

Если вы хотите ознакомиться с различными способами определения command и arguments для container в kubernetes , я рекомендую вам прочитать этот раздел в официальной документации kubernetes.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...