【问题标题】:Can a Service Fabric Aplication be deployed from within a Windows Docker Container to a cluster?是否可以将 Service Fabric 应用程序从 Windows Docker 容器内部署到群集?
【发布时间】:2019-03-09 07:18:28
【问题描述】:

在 Visual Studio (*.sfproj) 中构建 Service Fabric 项目时,会创建一个 Deploy-FabricApplication.ps1 脚本作为模板的一部分,以将此应用程序部署到 Azure(或在任何地方运行的 Service Fabric,就此而言)。我正在寻找一种方法将该机制容器化为 Windows Docker 映像的一部分,因为我们的构建和部署过程是容器化的。有没有办法在 Windows Docker 容器中运行此脚本,如果可以,映像需要具备哪些先决条件?

【问题讨论】:

  • 我认为这个问题还不够清楚,您是否需要在 docker 容器内部署集群(如下面的答案建议),或者您想从要部署的 docker 容器内创建应用程序服务结构集群?
  • @DiegoMendes - 我想将 Docker 容器中的应用程序部署到 Azure 上运行的 Service Fabric 群集。基本上,我想从容器中运行 Deploy-FabricApplication.ps1 脚本,将其指向在 Azure 上运行的 URL。因此,所有需要部署的工具都需要进行 Docker 化。应用程序本身是在其他地方构建的,只是为了解决这个问题而假设已经存在。

标签: visual-studio azure docker azure-service-fabric


【解决方案1】:

更新:

作为 Service Fabric 6.4 的一部分发布的 Service Fabric SDK 3.3.617 现在可以安装在容器中以构建和部署 Service Fabric 项目。这可以使用以下方法在 Dockerfile 中完成:

ADD https://download.microsoft.com/download/D/D/D/DDD408E4-6802-47FB-B0A1-ECF657BEB35F/MicrosoftServiceFabric.6.4.617.9590.exe C:\TEMP\MicrosoftServiceFabricRuntime.exe

ADD https://download.microsoft.com/download/D/D/D/DDD408E4-6802-47FB-B0A1-ECF657BEB35F/MicrosoftServiceFabricSDK.3.3.617.msi C:\TEMP\MicrosoftServiceFabricSDK.msi

RUN C:\TEMP\MicrosoftServiceFabricRuntime.exe /accepteula /sdkcontainerclient /quiet

RUN msiexec.exe /i "C:\TEMP\MicrosoftServiceFabricSDK.msi" /qn 

Here is an example Dockerfile

原答案:

事实证明,这可不是一件小事。此脚本需要安装 Windows Service Fabric SDK。安装 Service Fabric SDK 的推荐(也是唯一受支持的)方法是通过 WebPI,is available here。可以对 WebPI 进行 Dockerize 化,但是有一个问题。 WebPI 安装程序由三个组件组成; Service Fabric SDK、Service Fabric 运行时和 Visual Studio 的 Service Fabric 工具。 WebPI 安装程序将安装所有这些。不幸的是,Service Fabric Runtime(在撰写本文时)无法在 Docker 容器下运行,因为它想要安装内核级驱动程序。这个bug是being tracked here,但是已经开放了将近一年没有真正的进展。这意味着无法在 Docker 容器中运行 Service Fabric 集群,但 SDK 和工具肯定仍然可以运行,对吗?不幸的是,没有办法告诉安装程序只安装 SDK 和工具,而不是运行时。

所以,也许有一种不受支持的方式来安装 SDK 和工具。事实证明,release notes 引用了各个组件的各种 MSI。

SDK Available Here

Tools for Visual Studio Available Here

从 Dockerfile 运行 msiexec.exe 相当简单,这意味着我们应该能够以这种方式安装 SDK。没有。不幸的是,msiexec 将失败并出现通用 1603 代码。如果你在详细模式下运行 msiexec 并输出一个日志文件,你可以深入这个错误并查看根本原因:

MSI (s) (78:34) [19:07:56:049]:产品:Microsoft Azure 服务 Fabric SDK -- 此产品需要 Service Fabric Runtime 已安装。

此产品需要安装 Service Fabric Runtime。行动 19:07:56 结束:启动条件。返回值 3。

所以,我们又被击落了。我没有发现 Service Fabric SDK 的其他打包版本(Chocolatey 有一个,但它只是启动 WebPI 安装程序),这留下了一个最终解决方案;我们在没有安装程序帮助的情况下手动安装 SDK。这需要对安装程序所做的进行反向工程,并将其集成到我们的 Dockerfile 中。

SDK 安装程序会做一些事情。它将一堆文件复制到c:\program files\microsoft sdks\service fabric\,将一堆文件复制到c:\program files\microsoft service fabric\。它也是 GAC 的一堆东西(例如 System.Fabric.dll),向注册表添加了一些东西,并且还安装了一个 Powershell 模块。我们需要做所有这些事情才能让脚本运行。

我最终做的是将关键文件夹挂载为 Docker 卷,以便我可以在容器中使用它们:

docker run `
  -v 'c:\program files\microsoft sdks\service fabric\tools\psmodule\servicefabricsdk:C:\ServiceFabricModules' `
  -v 'c:\program files\microsoft service fabric\bin\fabric\fabric.code:C:\ServiceFabricCode' `
  -v 'c:\program files\microsoft service fabric\bin\servicefabric:C:\ServiceFabricBin' `
  -e ModuleFolderPath=C:\ServiceFabricModules `
  -it build-agent powershell

首先,我需要共享c:\program files\microsoft sdks\service fabric\tools\psmodule\servicefabricsdk 目录,其中包含Deploy-FabricApplication.ps1 脚本加载的Powershell 模块:

Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1"

接下来,我们需要分享c:\program files\microsoft service fabric\bin\fabric\fabric.code,因为它有一堆安装程序 GAC 的 DLL。

最后,我们分享c:\program files\microsoft service fabric\bin\servicefabric,因为该目录包含 SDK 安装的 PowerShell 模块。

当容器启动时,我们需要做以下事情:

首先,使用 PowerShell 注册模块:

Copy-Item C:\ServiceFabricBin C:\windows\system32\WindowsPowerShell\v1.0\modules\ServiceFabric -Recurse

执行此操作后,Get-Module -ListAvailable 将显示 ServiceFabric 模块。但是,不会加载任何导出,因为它缺少一堆 DLL。安装程序将这些 DLL 放在 GAC 中,但 GAC 是哑的,所以让我们将这些 DLL 放在同一个目录中,以便模块找到它们:

Copy-Item C:\ServiceFabricCode\System.Fabric*.dll C:\windows\system32\WindowsPowerShell\v1.0\modules\ServiceFabric -Recurse

在此之后,您应该能够运行 Get-Module -ListAvailable 并看到 ServiceFabric 模块已完全加载。

还有最后一件事要做。 Deploy-FabricApplication.ps1 脚本导入 ServiceFabricSDK.psm1 模块(见上文)。但是$ModuleFolderPath 是什么?好吧,默认情况下,脚本会在注册表中查找此值,当然安装程序会为您设置。我们不想搞砸 Docker 镜像的注册表,所以让我们更改脚本以查看环境变量:

$ModuleFolderPath = $ENV:ModuleFolderPath
Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1"

现在我们可以在运行 Docker 容器(或从 Dockerfile)时设置该环境变量。显然,如果您不想修改Deploy-FabricApplication.ps1 文件,也可以将其设置为HKLM:\SOFTWARE\Microsoft\Service Fabric SDK\FabricSDKPSModulePath。我是相当反注册的,所以环境变量(或者如果你真的不在乎,只是硬代码)对我来说更有意义。

另请注意,在部署脚本之前,您需要导入您的证书(您可以从 Key Vault 以 PFX 文件的形式下载):

Import-PfxCertificate -Exportable -CertStoreLocation Cert:\CurrentUser\My\ -FilePath C:\Certs\MyCert.pfx

我相信一个更高质量的版本是将所需的文件复制到 Dockerfile 中的映像中,而不是将它们作为卷安装,这样映像将更加独立,但这应该是相当简单的。此外,我相信 GAC 的 DLL 也可以在 NuGet 上使用,因此可以在 Docker 构建过程中通过 NuGet 下载所有这些文件。

另外,这是我完整的Dockerfile,我已使用它成功地将应用部署到 Service Fabric:

# escape=`

FROM microsoft/dotnet-framework:4.7.1

SHELL ["cmd", "/S", "/C"]

# Install Visual Studio Build Tools
ADD https://aka.ms/vs/15/release/vs_buildtools.exe C:\SETUP\vs_buildtools.exe
RUN C:\SETUP\vs_buildtools.exe --quiet --wait --norestart --nocache `
    --add Microsoft.VisualStudio.Workload.AzureBuildTools `
 || IF "%ERRORLEVEL%"=="3010" EXIT 0

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

# Our Deploy Certs
ADD ./Certs/ C:\Certs\

# Update Path (I forget if this was needed for something)
RUN SETX /M PATH $($Env:PATH + ';C:\ServiceFabricCode')

我希望这对某人有所帮助,但更希望微软修复他们的安装程序以删除运行时要求。

【讨论】:

  • 注意:看起来需要在路径中添加C:\ServiceFabricCode。关于Deploy-FabricApplication.ps1 的一些东西使用它来查找 FabricCommon.dll,但不确定到底是什么。看起来安装程序实际上也这样做了。
【解决方案2】:

安装 Azure 服务结构的最佳方法是创建一个 poweshell 文件并从 dockerfile 调用它

PowershellFile

Start-Process "msiexec" -ArgumentList '/i', 'C:/app/WebPlatformInstaller_amd64_en-US.msi', '/passive', '/quiet', '/norestart', '/qn' -NoNewWindow -Wait; 

& "C:\Program Files\Microsoft\Web Platform Installer\WebPICMD.exe" /Install /Products:MicrosoftAzure-ServiceFabric-CoreSDK /AcceptEULA

Dockerfile

RUN powershell -noexit "& ""./InstallServiceFabric.ps1"""

【讨论】:

  • 如上所述,安装程序不会在 Docker 下运行,因为运行时会尝试安装内核驱动程序并挂起。见Issue 711
猜你喜欢
  • 2018-01-27
  • 1970-01-01
  • 2018-02-20
  • 2019-02-17
  • 1970-01-01
  • 2017-08-06
  • 2021-09-14
  • 1970-01-01
  • 2019-12-02
相关资源
最近更新 更多