Exec-форма Entrypoint выполняется через оболочку - PullRequest
1 голос
/ 03 октября 2019

Я создаю образ докера на основе Windows:

FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019

# omitted for brevity

ENTRYPOINT ["c:\spinner.exe", "service", "w3svc", "-t", "c:\iislog\W3SVC\u_extend1.log"]

Базовый образ устанавливает оболочку на Powershell:

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

Насколько я понимаю, когда форма execкоманды ENTRYPOINT, команда будет выполнена без оболочки. Однако, когда я создаю контейнер, он завершается с ошибкой:

$ docker run -d -p 80:80 --isolation process --name pht site:local


$ docker logs pht

At line:1 char:77
+ ... ference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; [C:\\spin ...
+                                                                  ~
Missing ] at end of attribute or type literal.
At line:1 char:78
+ ... '; $ProgressPreference = 'SilentlyContinue'; [C:\\spinner.exe, servic ...
+                                                    ~~~~~~~~~~~~~~
Unexpected token ':\\spinner.exe' in expression or statement.
At line:1 char:92
+ ... ; $ProgressPreference = 'SilentlyContinue'; [C:\\spinner.exe, service ...
+                                                                 ~
Missing argument in parameter list.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordEx
   ception
    + FullyQualifiedErrorId : EndSquareBracketExpectedAtEndOfAttribute

И когда я проверяю остановленный контейнер, я вижу, что выполненная команда была через оболочку:

 "Entrypoint": [
                "powershell -Command $ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; [\"c:\\spinner.exe\", \"service\", \"w3svc\", \"-t\", \"c:\\iislog\\W3SVC\\u_extend1.log\"]"
            ],

AmЯ что-то здесь недопонимаю?

1 Ответ

1 голос
/ 03 октября 2019

Синтаксис exec требует формата JSON, что означает, что экземпляры \ в элементах массива должны быть экранированы как \\.

Поскольку ваша инструкция ENTRYPOINT, следовательно, не содержит допустимого массива JSON, похоже, что Docker возвращается к shell синтаксис и поэтому передает ваш ENTRYPOINTаргумент оболочки, который в вашем случае является PowerShell, как определено в вашей инструкции SHELL, и что приводит к команде сломанной оболочки . [1]

Синтаксически правильный ENTRYPOINT в формате exec - то есть действительный JSON - предотвращает участие оболочки, что является правильным подходом в этомcase , учитывая, что ваша команда содержит только литерал элементов.

Поэтому попробуйте следующее (\ экземпляров, экранированных как \\):

ENTRYPOINT ["c:\\spinner.exe", "service", "w3svc", "-t", "c:\\iislog\\W3SVC\\u_extend1.log"]

Таким образом, Docker должен выполнить следующую командную строку в контейнере:

c:\spinner.exe service w3svc -t c:\iislog\W3SVC\u_extend1.log

[1] В результате получается неверный аргумент ENTRYPOINT, ["c:\spinner.exe", "service", "w3svc", "-t", "c:\iislog\W3SVC\u_extend1.log"], считается одиночным аргументом, передаваемым в оболочку , как определено вашей SHELL инструкцией. Это означает добавление этого аргумента к последнему аргументу вашего массива SHELL, которому предшествует символ пробела. Когда результат объединяется в единую командную строку, внедренные символы " и \ должны быть \ -экранированы, что объясняет то, что вы видели в журналах.

...