Команды, переданные Kubernetes Job и Pod
У меня есть команда perl, которую мне нужно передать на задание kubernetes. Команда вычисляет и выводит значение числа пи с точностью до 2000 знаков.
perl -Mbignum =bpi -wle 'печатать bpi(2000)'
Я передал команду в yaml-файл задания, как показано ниже. Через kubectl файл yaml успешно создает задание и выводит значение числа пи.
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.
1 ответ
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
работает успешно, давая желаемый результат.
Обратите внимание, что при предоставлении 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
только с print
аргумент, который не имеет никакого смысла, поскольку требует очень конкретной команды, сообщающей ему, что следует напечатать. Это точно так же, как если бы вы запускали оболочку bash:
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)"
что, конечно, невозможно.
Если вы хотите ознакомиться с различными способами определения command
и это arguments
для container
в kubernetes я рекомендую вам прочитать этот раздел в официальной документации kubernetes.