2

我正在构建一个基于 Windows 的 docker 映像:

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,该命令将在没有 shell 的情况下执行。但是,当我创建容器时,它会失败并出现以下错误:

$ 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

当我检查停止的容器时,我看到执行的命令是通过 shell:

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

我在这里误解了什么吗?

4

1 回答 1

2

exec语法需要 JSON 格式,这意味着数组元素中的\实例必须转义为\\.

由于您的ENTRYPOINT指令因此不包含有效的 JSON 数组,看起来 Docker 正在回退到shell语法,因此将您的ENTRYPOINT参数传递给 shell,在您的情况下是 PowerShell,如您的SHELL指令中所定义 - 这会导致损坏外壳命令[1]

execENTRYPOINT格式的语法正确- 即有效的 JSON -可以防止涉及 shell,在这种情况下这是正确的方法,因为您的命令仅包含文字元素。

因此,请尝试以下操作(\实例转义为\\):

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"]被视为单个参数 -根据 JSON 规则(字符加倍)进行转义的逐字字符串-按照您的说明\传递给shellSHELL。这意味着将该参数附加到SHELL数组的最后一个参数,前面有一个空格字符。你在日志中看到的就是证据。

于 2019-10-03T04:17:25.223 回答