【问题标题】:.Net Core windows service not installing in a docker container.Net Core Windows 服务未安装在 docker 容器中
【发布时间】:2021-07-17 13:09:41
【问题描述】:

我正面临一个非常特殊的问题。我有一个 .net 核心 Windows 服务 (XYZ),其安装程序 (XYZ.msi) 是使用 Wix 创建的。我正在尝试将此服务安装在容器中。该服务被安装,然后 Windows 尝试将其注册为服务,该服务超时在系统事件日志The XYZ Service (XYZ) service failed to start due to the following error: %%1053 A timeout was reached (30000 milliseconds) while waiting for the XYZ service (XYZ) service to connect. 中向我提供以下“信息”,然后该服务被卸载,这是预期的。

当我进一步检查应用程序事件日志时,我得到了这些

Product: XYZ -- Error 1920. Service 'XYZ' (XYZ) failed to start. Verify that you have sufficient privileges to start system services.

Windows Installer installed the product. Product Name: XYZ. Product Version: 0.0.0.0. Product Language: 1033. Manufacturer: .... Installation success or error status: 1603.

所以为了理解这些错误代码,我参考了Error Code 1603 和错误 1920 上的一些其他链接,但由于这些非常通用,这些链接没有用。

相同的服务在本地和不同的服务器上运行良好。

XYZ.msi所在的容器内的文件夹有这些权限

Path   : Microsoft.PowerShell.Core\FileSystem::C:\app
Owner  : NT AUTHORITY\SYSTEM
Group  : NT AUTHORITY\SYSTEM
Access : BUILTIN\Administrators Allow  FullControl
         BUILTIN\Administrators Allow  268435456
         NT AUTHORITY\SYSTEM Allow  FullControl
         NT AUTHORITY\SYSTEM Allow  268435456
         NT AUTHORITY\Authenticated Users Allow  Modify, Synchronize
         NT AUTHORITY\Authenticated Users Allow  -536805376
         BUILTIN\Users Allow  ReadAndExecute, Synchronize
         BUILTIN\Users Allow  -1610612736
Audit  :
Sddl   : O:SYG:SYD:(A;ID;FA;;;BA)(A;OICIIOID;GA;;;BA)(A;ID;FA;;;SY)(A;OICIIOID;GA;;;SY)(A;ID;0x1301bf;;;AU)(A;OICIIOID;SDGXGWGR;;;AU)(A;ID;0x1200a9;;;BU)(A;OICIIOID;GXGR;;;BU)

另外我假设所有的安装都是使用容器内的 ContainerAdministrator 帐户进行的。

现在我无法弄清楚问题是什么,如何进一步排除故障,以及如果它是权限问题,我需要设置哪些权限。在这方面的任何帮助将不胜感激。谢谢!

编辑: dockerFile 看起来像这样

FROM mcr.microsoft.com/windows/servercore:ltsc2019-amd64
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
WORKDIR /app
COPY [".","."]
RUN  ["powershell.exe", "./install.cmd"]

WiX .wxs 代码

<Fragment>
    <ComponentGroup Id="ServiceComponents" Directory="APPLICATIONFOLDER">
      <Component Id="ServiceComponent" Guid="649E5964-126A-4DF5-95CF-CE7C2474E981">
        <File Id="xyz.exe" KeyPath="yes" Vital="yes" DiskId="1" Source="..\xyz\bin\$(var.Platform)\$(var.Configuration)\netcoreapp3.1\win-x64\xyz.exe"/>
        <ServiceInstall
          Id="ServiceInstaller"
          Type="ownProcess"
          Vital="yes"
          Name="xyz"
          DisplayName="$(var.ProductName)"
          Description="$(var.Description)"
          Start="auto"
          Account="NT AUTHORITY\LocalService"
          ErrorControl="normal" Interactive="no">
          <ServiceConfig DelayedAutoStart="yes" OnInstall="yes" OnReinstall="yes" />
          <util:ServiceConfig FirstFailureActionType="restart" SecondFailureActionType="restart" ThirdFailureActionType="none" ResetPeriodInDays="1" RestartServiceDelayInSeconds="0" />
        </ServiceInstall>
        <ServiceControl
          Id="ServiceController"
          Name="xyz"
          Start="install"
          Stop="both"
          Remove="both"
          Wait="yes" />
      </Component>
    </ComponentGroup>
  </Fragment>

【问题讨论】:

  • 您是否真正验证过它在安装时作为 ContainerAdministrator 运行?你的 Dockerfile 是什么样的?
  • 这只是一个假设,尚未验证。有没有办法我可以做到这一点?我也会添加我的 dockerfile
  • 您是否尝试过构建 2019 ltsc2019 服务器核心 VM 并在其上安装 MSI?
  • 尝试同时使用mcr.microsoft.com/windows/servercore:ltsc2019-amd64mcr.microsoft.com/windows/servercore:ltsc2019
  • 要检查什么用户在运行,你只需要添加一条类似RUN echo %USERNAME%的指令,它就会在docker build的输出中输出它是什么用户。根据您的 Dockerfile,它将作为 ContainerUser 运行,而不是 ContainerAdministrator。

标签: docker .net-core wix user-permissions


【解决方案1】:

我个人从未尝试在容器内安装 MSI。我使用过的容器(主要是基于 linux 的)容器 simple 会将 EXE 称为控制台应用程序,而实际上它并不是一个服务。我会根据您所写的内容假设可以在 Windows 容器内安装 MSI。

话虽如此,1920 错误只是意味着服务没有启动。 “验证您是否拥有管理员”一直是用词不当。要在 Windows 中进行故障排除,我通常会在此处暂停安装程序并尝试手动运行 EXE 以查看控制台是否出现任何错误。通常,这将是一条消息,说明 .NET (Core) 或未安装某些依赖项。如果 EXE 实际启动并且您在路上遇到了一些异常,那么这将需要额外的调试。

我不确定您是如何劫持 Windows 容器的,但您需要执行类似于调试/分析问题的操作。基本上它可以在一台机器上运行,而不是你的容器,因为你的 docker 镜像没有其他机器有的东西,而且你的代码也不喜欢它。

【讨论】:

  • 结果与 exe 相同,并且 exe/msi 在不同的 vm 服务器和本地计算机上运行良好。我将尝试从 applicaton.exe 创建服务,而不是安装它。我最好的猜测是,如果应用程序是手动注册并开始运行的,那么它必须是 wix 安装程序代码
  • 我从不同的角度出发,完全不同意。 WiX/MSI 是反自我注册。如果该服务在使用 InstallUtil 调用时正在做一些特殊的事情,那在我的书中并不是一件好事。这些事情应该由 WiX 完成。此外,另一个 VM 服务器不是 docker 映像,因此它并不能告诉您任何信息。
  • PS- 如果您只想跳过 MSI 和 WiX 并在您的 dockerfile 中放置一个 InstallUtil 命令并将其注册到可接受路径的图像/容器中。 MSI 更多的是一种服务器/桌面技术,而不是真正的无服务器云原生技术。
  • “反自注册”是什么意思?该服务也没有做任何特别的事情。我只是使用docker run 访问容器,然后执行msi ps&gt; .\xyz.msi /q。服务注册代码在 WiX 本身中。我不确定我是否更容易理解我的设置。我会记住不要将 MSI 用于我的容器,而是使用 exe。
  • WiX 中的 ServiceInstall 和 ServiceControl 元素很好。如果您在 ServiceInstaller 类的 Install、Rollback 或 Uninstall 方法中实现了任何自定义代码,就会出现问题。此代码将被视为自我注册,因为服务代码正在执行逻辑而不是 MSI 执行逻辑。此代码仅通过 InstallUtil 执行。 MSI 不执行这些方法,因此如果他们设置了任何依赖项,则不会设置它们,这可能是问题的根源。我过去见过的一个常见示例是设置 EventLog/EventSource。这应该在 WiX 中完成。
【解决方案2】:

我会首先尝试通过安装启用详细日志记录的 MSI 来找到问题的根本原因。 Here 你可以找到一个如何做到这一点的例子。日志文件应提供有关所发生情况的更多详细信息(也许您的安装程序中有一些失败的自定义操作以及日志文件中臭名昭著的“值 3”)。

我还会尝试修改 wxs 文件,以便安装不会启动服务(通过删除 ServiceControl Start="install" 并将 ServiceInstall Start="auto" 替换为 ServiceInstall Start="demand")。通过此修改,MSI 的安装可能会成功。然后您是否能够启动 xyz.exe(直接,而不是作为服务)?如果不是,则问题不在于安装,而在于可执行文件。您是否能够在这些更改后手动启动服务?

【讨论】:

  • 我开始认为它不是与安装程序有关,而是与服务本身有关。当我手动运行服务时,它会给我一个 1053 错误(服务超时)。到目前为止,我只是想找到根本原因。
  • 这正是我在回答中告诉你的! :)
【解决方案3】:

虽然我仍在调查 .net 核心 Windows 服务的行为,并已启动另一个线程 here 以听取 SO 社区对此的看法,但问题似乎在于服务的实施方式。这是一种奇怪的行为,但如果我不使用 .net core 3 附带的 Worker Template 而是使用 ServiceBase 和 IHostingLifetime 在 .net core 2.1 中创建服务,它在所有环境中都可以正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-05
    • 2018-08-15
    • 1970-01-01
    相关资源
    最近更新 更多