visual-studio - 可以将Service Fabric应用程序从Windows Docker容器内部署到群集吗?

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

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

最佳答案

更新:

作为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进行Docker化,但是存在一个问题。 WebPI安装程序由三个组件组成; Service Studio SDK,Service Fabric运行时和Visual Studio的Service Fabric工具。 WebPI安装程序将安装所有这些文件。不幸的是,Service Fabric Runtime(在撰写本文时)无法在Docker容器下运行,因为它想安装内核级驱动程序。这个错误是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]: Product: Microsoft Azure Service Fabric SDK -- This product requires Service Fabric Runtime to be installed.

This product requires Service Fabric Runtime to be installed. Action ended 19:07:56: LaunchConditions. Return value 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上进行设置。我是相当反对注册的人,因此环境变量(如果您真的不在乎,则只是硬代码)对我来说更有意义。

还要注意,在脚本部署之前,您需要导入证书(您可以以PFX文件的形式从Key Vault中下载证书):
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')

我希望这对某人有帮助,但是希望更多,所以我希望Microsoft修复其安装程序以消除运行时要求。

关于visual-studio - 可以将Service Fabric应用程序从Windows Docker容器内部署到群集吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52637549/

相关文章:

javascript - 从asp.net图表控件打开一个新窗口

c# - 发出HTTP POST请求时捕获ElasticSearch异常

azure - 从 Azure 媒体服务获取 mp3

docker - 如何从 Sveltekit 应用构建 docker 镜像

visual-studio - Visual Studio 2017 占用本地 AppData 文件夹中的磁盘空间

c++ - 为什么 Visual Studio CRT 内存报告显示 CRT block

c# - Dotnet Core 2.2 - Azure AD 身份验证工作但角色库返回访问被拒绝

azure - 在 Polybase 中使用 unicode 字段终止符

docker - concourse 无法放入私有(private) docker 注册表,重试直到出现 500 错误

mysql - 使用客户端连接到docker网络内的mysql