能否将 Service Fabric 应用程序从 Windows Docker 容器部署到集群?
Can a Service Fabric Aplication be deployed from within a Windows Docker Container to a cluster?
在 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 项目。这可以在 Docker 文件中使用以下命令完成:
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
原答案:
事实证明,这是一个不小的壮举。此脚本需要安装 Windows Service Fabric SDK。推荐的(也是唯一支持的)安装 Service Fabric SDK 的方式是通过 WebPI,is available here. It's possible to Dockerize the WebPI, however there's a problem. The WebPI installer consists of three components; the Service Fabric SDK, the Service Fabric Runtime, and the Service Fabric Tools for Visual Studio. The WebPI installer will install all of them. Unfortunately, the Service Fabric Runtime (as of this writing) cannot run under a Docker container since it wants to install a kernel level driver. This bug is being tracked here,但已经开放了将近一年,没有任何实质性进展。这意味着不能 运行 Docker 容器中的 Service Fabric 集群,但 SDK 和工具肯定仍然能够 运行,对吗?不幸的是,没有办法告诉安装程序只安装 SDK 和工具,而不是 运行时间。
所以,也许有一种不受支持的方法可以只安装 SDK 和工具。事实证明,release notes 引用了各个组件的各种 MSI。
Tools for Visual Studio Available Here
从 Docker 文件到 运行 msiexec.exe 相当简单,这意味着我们应该能够以这种方式安装 SDK。没有。 Unfo运行ately,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。这需要对安装程序所做的进行逆向工程,并将其集成到我们的 Docker 文件中。
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
,因为它有一堆安装程序GACs的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 容器(或来自我们的 Docker 文件)时设置该环境变量。显然,如果您不想修改 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
我相信一个更高生产质量的版本是将所需的文件复制到您的 Docker 文件中的图像中,而不是将它们作为卷安装,这样图像会更加独立,但应该相当直截了当。此外,我相信经过 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 修复他们的安装程序以删除 运行时间要求。
安装 Azure 服务结构的最佳方法是创建一个 poweshell 文件并从 dockerfile 中调用它
Powershell 文件:
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"""
在 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 项目。这可以在 Docker 文件中使用以下命令完成:
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
原答案:
事实证明,这是一个不小的壮举。此脚本需要安装 Windows Service Fabric SDK。推荐的(也是唯一支持的)安装 Service Fabric SDK 的方式是通过 WebPI,is available here. It's possible to Dockerize the WebPI, however there's a problem. The WebPI installer consists of three components; the Service Fabric SDK, the Service Fabric Runtime, and the Service Fabric Tools for Visual Studio. The WebPI installer will install all of them. Unfortunately, the Service Fabric Runtime (as of this writing) cannot run under a Docker container since it wants to install a kernel level driver. This bug is being tracked here,但已经开放了将近一年,没有任何实质性进展。这意味着不能 运行 Docker 容器中的 Service Fabric 集群,但 SDK 和工具肯定仍然能够 运行,对吗?不幸的是,没有办法告诉安装程序只安装 SDK 和工具,而不是 运行时间。
所以,也许有一种不受支持的方法可以只安装 SDK 和工具。事实证明,release notes 引用了各个组件的各种 MSI。
Tools for Visual Studio Available Here
从 Docker 文件到 运行 msiexec.exe 相当简单,这意味着我们应该能够以这种方式安装 SDK。没有。 Unfo运行ately,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。这需要对安装程序所做的进行逆向工程,并将其集成到我们的 Docker 文件中。
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
,因为它有一堆安装程序GACs的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 容器(或来自我们的 Docker 文件)时设置该环境变量。显然,如果您不想修改 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
我相信一个更高生产质量的版本是将所需的文件复制到您的 Docker 文件中的图像中,而不是将它们作为卷安装,这样图像会更加独立,但应该相当直截了当。此外,我相信经过 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 修复他们的安装程序以删除 运行时间要求。
安装 Azure 服务结构的最佳方法是创建一个 poweshell 文件并从 dockerfile 中调用它
Powershell 文件:
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"""