Mik*_*sen 3 azure visual-studio 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
Run Code Online (Sandbox Code Playgroud)
原答案:
事实证明,这绝非易事。此脚本需要安装 Windows Service Fabric SDK。安装 Service Fabric SDK 的推荐(且仅受支持)方法是通过 WebPI,可在此处获得。可以对 WebPI 进行 Dockerize,但是有一个问题。WebPI 安装程序由三个组件组成;Service Fabric SDK、Service Fabric Runtime 和 Service Fabric Tools for Visual Studio。WebPI 安装程序将安装所有这些。不幸的是,Service Fabric 运行时(在撰写本文时)无法在 Docker 容器下运行,因为它要安装内核级驱动程序。这个错误是正在此处跟踪,但已经开放近一年了,并没有真正的进展。这意味着不能在 Docker 容器中运行 Service Fabric 集群,但 SDK 和工具肯定应该仍然能够运行,对吗?不幸的是,没有办法告诉安装程序只安装 SDK 和工具,而不是运行时。
因此,也许有一种不受支持的方式可以只安装 SDK 和工具。事实证明,发行说明引用了各个组件的各种 MSI。
从 Dockerfile 运行 msiexec.exe 相当简单,这意味着我们应该能够以这种方式安装 SDK。不。不幸的是,msiexec 将失败并显示通用 1603 代码。如果以详细模式运行 msiexec 并输出日志文件,则可以深入研究此错误并查看根本原因:
MSI (s) (78:34) [19:07:56:049]:产品:Microsoft Azure Service Fabric SDK -- 此产品需要安装 Service Fabric Runtime。
此产品需要安装 Service Fabric Runtime。行动在 19:07:56 结束:LaunchConditions。返回值 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
Run Code Online (Sandbox Code Playgroud)
首先,我需要共享c:\program files\microsoft sdks\service fabric\tools\psmodule\servicefabricsdk
包含Deploy-FabricApplication.ps1
脚本加载的 Powershell 模块的目录:
Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1"
Run Code Online (Sandbox Code Playgroud)
接下来,我们需要分享,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
Run Code Online (Sandbox Code Playgroud)
执行此操作后,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
Run Code Online (Sandbox Code Playgroud)
在此之后,您应该能够运行Get-Module -ListAvailable
并看到 ServiceFabric 模块完全加载。
最后还有一件事要做。该Deploy-FabricApplication.ps1
脚本进口ServiceFabricSDK.psm1
模块(见上文)。但什么是$ModuleFolderPath
?嗯,脚本默认在注册表中查找此值,当然安装程序会为您设置。我们不想弄乱 Docker 镜像的注册表,所以让我们更改脚本以查看环境变量:
$ModuleFolderPath = $ENV:ModuleFolderPath
Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1"
Run Code Online (Sandbox Code Playgroud)
现在我们可以在运行 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
Run Code Online (Sandbox Code Playgroud)
我相信一个更高质量的版本是将所需的文件复制到 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')
Run Code Online (Sandbox Code Playgroud)
我希望这对某人有所帮助,但更多的是我希望 Microsoft 修复他们的安装程序以删除运行时要求。
归档时间: |
|
查看次数: |
774 次 |
最近记录: |