更新:
作为 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')
我希望这对某人有所帮助,但更希望微软修复他们的安装程序以删除运行时要求。