Обновление:
Пакет Service Fabric SDK 3.3.617, выпущенный как часть Service Fabric 6.4, теперь можно устанавливать в контейнерах для создания и развертывания проектов 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
Вот пример Dockerfile
Оригинальный ответ:
Оказывается, это не маленький подвиг.Для этого сценария требуется установить Windows Service Fabric SDK.Рекомендуемый (и только поддерживаемый) способ установки Service Fabric SDK - через WebPI, который доступен здесь .Возможно докеризировать WebPI, однако есть проблема.Установщик WebPI состоит из трех компонентов;SDK Service Fabric, среда выполнения Service Fabric и инструменты Service Fabric для Visual Studio.Установщик WebPI установит их все.К сожалению, среда выполнения Service Fabric (на момент написания этой статьи) не может работать в контейнере Docker, поскольку она хочет установить драйвер уровня ядра.Эта ошибка отслеживается здесь , но была открыта почти год без реального прогресса.Это означает, что нельзя запустить кластер Service Fabric в контейнере Docker, но, конечно же, SDK и инструменты должны работать, верно?К сожалению, нет способа сказать установщику, что нужно устанавливать только SDK и инструменты, но не среду выполнения.
Так что, возможно, существует неподдерживаемый способ установки только SDK и инструментов.Оказывается, в заметках о выпуске есть ссылки на различные MSI для отдельных компонентов.
SDK, доступный здесь
Инструменты для Visual StudioДоступно здесь
Запускать msiexec.exe из Dockerfile довольно просто, что означает, что мы должны иметь возможность установить SDK таким образом.Нету.К сожалению, msiexec потерпит неудачу с общим кодом 1603.Если вы запускаете msiexec в подробном режиме и выводите файл журнала, вы можете разобраться в этой ошибке и увидеть основную причину:
MSI (78:34) [19:07:56:049]: Продукт: Microsoft Azure Service Fabric SDK - для установки этого продукта требуется среда выполнения Service Fabric.
Для установки этого продукта требуется среда выполнения Service Fabric.Действие завершено 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
, в котором содержится модуль Powershell, который загружает скрипт Deploy-FabricApplication.ps1
:
Import-Module "$ModuleFolderPath\ServiceFabricSDK.psm1"
Далее нам необходимо предоставить общий доступ к c:\program files\microsoft service fabric\bin\fabric\fabric.code
, так как в нем есть кучаDLL, которые установщик GAC.
Наконец, мы разделяем c:\program files\microsoft service fabric\bin\servicefabric
, потому что этот каталог содержит модуль PowerShell, установленный SDK.
Когда контейнер запускается, нам нужно сделать следующее:
Сначала зарегистрируйте модуль в 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) до того, как сценарий будет развернут:
Import-PfxCertificate -Exportable -CertStoreLocation Cert:\CurrentUser\My\ -FilePath C:\Certs\MyCert.pfx
Я считаю, что более производительной версией этого варианта будет копирование необходимых файлов в образ в вашем Dockerfileвместо того, чтобы монтировать их как тома, чтобы изображение было более автономным, но это должно быть достаточно прямым.Кроме того, я считаю, что библиотеки DLL, которые были GAC, также доступны в NuGet, поэтому можно было бы загрузить все эти файлы через NuGet во время процесса сборки Docker.
Кроме того, вот мои полные 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 исправит их установщик, чтобы убрать требование времени выполнения.