Развертывание приложения Service Fabric с сохранением состояния C# из Visual Studio в Linux

EDIT 04/06/18 = > обновленный вопрос с последним статусом


таким образом, у меня есть эта рабочая служба .Net 4.6 с состоянием, которая в настоящее время работает на моем кластере Windows Service Fabric, развернутом в Azure.

начиная с 09/2017, я должен иметь возможность перейти на Linux: https://blogs.msdn.microsoft.com/azureservicefabric/2017/09/25/service-fabric-6-0-release/

поэтому я пытаюсь развернуть его на Linux, чтобы я мог сохранить затраты.

  1. во-первых, я перенес весь свой код с .Net 4.6 на .Net Core 2.0. Теперь я могу скомпилировать свои двоичные файлы без проблем. Я в основном создал новые проекты .Net Core, а затем переместил весь свой исходный код из проектов .Net 4.6 в новые проекты .Net Core.

  2. затем я обновил приложение Service Fabric. Я удалил свои предыдущие службы SF из своего sfproj, затем я добавил свое новое .Net Core те.

enter image description here

похоже, что есть предупреждение (ничего в окне вывода, хотя), но оно все равно здесь, Если я попытаюсь создать новую пустую службу состояния с помощью .Net core 2.0 через шаблон, предоставленный Service Fabric Tools 2.0 (beta):

enter image description here

так что я собираюсь жить с ней.

  1. на моей машине dev я изменил 2 проекта csproj, которые содержат мои службы с состоянием, чтобы они могли работать локально как исполняемые файлы Windows. Я использовал С Win7-х64 runtimeIdentifier.

запуск моего кластера SF локально на моей машине Windows в порядке.

  1. затем я немного изменил предыдущие файлы csproj для Linux. Я использовал ubuntu.16.10-x64 runtimeIdentifier.

также я изменил ServiceManifest.xml-файл для целевой linux-совместимый binary:

  <!-- Code package is your service executable. -->
  <CodePackage Name="Code" Version="1.9.6">
    <EntryPoint>
      <ExeHost>
        <Program>entryPoint.sh</Program>
      </ExeHost>
    </EntryPoint>
  </CodePackage>

entryPoint.sh является основным скриптом, который в конечном итоге выполняется:

dotnet $DIR/MyService.dll
  1. затем я успешно развернулся в своем защищенном кластере SF Linux из Visual Studio. К сожалению, у меня есть следующие ошибки для обеих моих служб stateful:

enter image description here

событие ошибки: SourceId= ' System.Хостинг, Свойство= 'CodePackageActivation: Code: EntryPoint'. Произошла ошибка во время CodePackage активация.Узел службы завершается выходом код:134

похоже, что мой двоичный сбой при запуске. Итак, вот мои вопросы:

  • является ли подход правильным для развертывания службы с состоянием C# .Net Core SF в Linux из Visual Studio?

редактировать: глядя внутри таблицы LinuxsyslogVer2v0, я получаю следующую ошибку:

starthost.sh[100041]: необработанное исключение: Система.ИО.FileLoadException: не удалось загрузить файл или сборку - Система.Нарезка резьбы.Поток, версия=4.1.0.0, культура=нейтральный, PublicKeyToken=b03f5f7f11d50a3a'. Манифеста сборки расположены определение не соответствует ссылке на сборку. (Исключение из HRESULT: 0x80131040)

Я нашел следующий отчет об ошибке:https://github.com/dotnet/sdk/issues/1502 К сожалению, я все еще получаю ошибку без использования MSBuild (используя dotnet deploy).

редактировать: уточнения:

  • мой босс хочет, чтобы я работал на Linux, потому что, начиная с машин D1v2, это половина цены по сравнению с машинами Windows (без лицензии и т. д.)
  • мои службы .NET Core 2.0 успешно работают в Windows. Таким образом, порт .NET Core должен быть в порядке.

3 ответов


Итак, это была настоящая заноза в заднице, чтобы заставить ее работать должным образом. Но это работает. Ну, вроде того.


во-первых, надежные службы все еще находятся в предварительном просмотре в Linux: https://github.com/Microsoft/service-fabric/issues/71

полная поддержка Linux должна появиться очень скоро (на самом деле она должна быть доступна уже по предыдущей ссылке...).

теперь для деталей о как процедить, вот некоторая информация, чтобы помочь другим, потому что нет ничего об этом в документации Microsoft, и я буквально потерял 3 дней, пытаясь заставить его работать.

1. Используйте .NET Core 2.0 для своих проектов.

он поддерживается в Linux. На preview пока, но он работает.

2. Используйте правильный RID для своих проектов.

на сегодняшний день (апрель 2018), право RID использовать является ubuntu.16.04-x64. Отредактируйте csproj файлы Надежные сервисные проекты и установить Рид так:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
    <RuntimeIdentifier>ubuntu.16.04-x64</RuntimeIdentifier>
    <Platforms>AnyCPU;x64</Platforms>
  </PropertyGroup>

самое интересное, вы должны иметь возможность предоставлять несколько Ридов с помощью он просто не работает. При создании проекта из Visual Studio я получаю следующий каталог только:

bin/Debug/netcoreapp2.0/

только DLL, нет допустимой точки входа. Нет!-Папка -11-->, нет ubuntu.16.04-x64, нет ничего. Это ошибка, которая должна быть исправлена, но это не так (я использую Visual Studio 15.6.2 на сегодняшний день). См.https://github.com/dotnet/core/issues/1039

3. Вам нужна действительная точка входа для вашей службы.

в Windows это исполняемый файл (*.исполняемый.) В Linux это не так. Я закончил тем, что получил пример Linux c# и скопировал / вставил точка входа. https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-create-your-first-linux-application-with-csharp

так что в основном у меня теперь есть на моем ServiceManifest.xml файл каждой надежной службы следующий EntryPoint :

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="XXXX"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <!-- This is the name of your ServiceType.
         This name must match the string used in RegisterServiceType call in Program.cs. -->
    <StatefulServiceType ServiceTypeName="YYY" HasPersistedState="true" />
  </ServiceTypes>

  <!-- Code package is your service executable. -->
  <CodePackage Name="Code" Version="1.0.0">
    <EntryPoint>
      <ExeHost>
        <Program>entryPoint.sh</Program>
      </ExeHost>
    </EntryPoint>
  </CodePackage>

entryPoint.sh следующим образом:

#!/usr/bin/env bash
check_errs()
{
  # Function. Parameter 1 is the return code
  if [ "" -ne "0" ]; then
    # make our script exit with the right error code.
    exit 
  fi
}

DIR=`dirname `
echo 0x3f > /proc/self/coredump_filter
source $DIR/dotnet-include.sh
dotnet $DIR/NAME_OF_YOUR_SERVICE_DLL.dll $@
check_errs $?

dotnet-include.sh следующим образом:

#!/bin/bash
. /etc/os-release
linuxDistrib=$ID
if [ $linuxDistrib = "rhel" ]; then
  source scl_source enable rh-dotnet20
  exitCode=$?
  if [ $exitCode != 0 ]; then
    echo "Failed: source scl_source enable rh-dotnet20 : ExitCode: $exitCode"
    exit $exitCode
  fi
fi

оба находятся внутри . Я указал для обоих их свойств так что Build Action is "Content" и Copy to Output Directory это "Copy always".

enter image description here

4. Не создавайте с помощью MSBuild !!

Да, он также должен создавать пакеты Linux, или, по крайней мере, так кажется, потому что MSBuild может создавать следующие файлы, когда вы щелкните правой кнопкой мыши на своем проекте и нажмите "построить":

enter image description here

не доверяйте очевидному успеху операции, он будет несчастливо не в состоянии правильно выполнить при развертывании. Некоторые *.so файлы отсутствуют и другие вопросы. MSBuild глючит, как ад, и плохо себя ведет в отношении зависимостей.

см., например, этот отчет об ошибке:https://github.com/dotnet/sdk/issues/1502 Все еще не исправлено после почти года...

или https://github.com/dotnet/core/issues/977 (это тоже есть).

5. Напишите сценарий PowerShell, чтобы создать материал себе.

я закончил изобретать колесо, используя следующий скрипт для создания моего пакета:

# Creating binaries for service 1
cd DIRECTORY_OF_MY_SERVICE_1
dotnet publish -c Release -r ubuntu.16.04-x64

# Creating binaries for service 2
cd ..\DIRECTORY_OF_MY_SERVICE_2
dotnet publish -c Release -r ubuntu.16.04-x64

# Creating binaries for service 3
cd ..\DIRECTORY_OF_MY_SERVICE_3
dotnet publish -c Release -r ubuntu.16.04-x64

# Copying ApplicationManifest.xml
cd ..
mkdir PKG\ServiceFabricApplication
echo F|xcopy "ServiceFabricApplication\ApplicationPackageRoot\ApplicationManifest.xml" "PKG\ServiceFabricApplication\ApplicationManifest.xml" /sy

# Copying Service1 files
mkdir "PKG\ServiceFabricApplication\Service1Pkg"
mkdir "PKG\ServiceFabricApplication\Service1Pkg\Code"
xcopy "Service1\PackageRoot\*" "PKG\ServiceFabricApplication\Service1Pkg" /sy /D
xcopy "Service1\bin\Release\netcoreapp2.0\ubuntu.16.04-x64\publish\*" "PKG\ServiceFabricApplication\Service1Pkg\Code" /sy

# Copying Service2 files
mkdir "PKG\ServiceFabricApplication\Service2Pkg"
mkdir "PKG\ServiceFabricApplication\Service2Pkg\Code"
xcopy "Service2\PackageRoot\*" "PKG\ServiceFabricApplication\Service2Pkg" /sy /D
xcopy "Service2\bin\Release\netcoreapp2.0\ubuntu.16.04-x64\publish\*" "PKG\ServiceFabricApplication\Service2Pkg\Code" /sy

# Copying Service3 files
mkdir "PKG\ServiceFabricApplication\Service3Pkg"
mkdir "PKG\ServiceFabricApplication\Service3Pkg\Code"
xcopy "Service3\PackageRoot\*" "PKG\ServiceFabricApplication\Service3Pkg" /sy /D
xcopy "Service3\bin\Release\netcoreapp2.0\ubuntu.16.04-x64\publish\*" "PKG\ServiceFabricApplication\Service3Pkg\Code" /sy

# Compresses the package
Write-host "Compressing package..."
Copy-ServiceFabricApplicationPackage -ApplicationPackagePath .\PKG\ServiceFabricApplication -CompressPackage -SkipCopy

sfproj файл-это проект, связанный с Visual Studio / MSBuild, поэтому вам нужно создать все самостоятельно. Сценарий выше создает тот же контент, что и pkg папка, созданная MSBuild при создании вашего sfproj использование Visual Studio. Он копирует все на PKG папка в корне вашего решения.

структура пакета подробно здесь: https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/service-fabric/service-fabric-package-apps.md

6. Теперь пришло время для развертывания!

на данный момент я больше не доверял Visual Studio, поэтому я создал свой собственный сценарий PowerShell:

. .\ServiceFabricApplication\Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath '.\PKG\ServiceFabricApplication' -PublishProfileFile '.\ServiceFabricApplication\PublishProfiles\Cloud.xml' -DeployOnly:$false -ApplicationParameter:@{} -UnregisterUnusedApplicationVersionsAfterUpgrade $false -OverrideUpgradeBehavior 'None' -OverwriteBehavior 'SameAppTypeAndVersion' -SkipPackageValidation:$false -ErrorAction Stop

он использует Deploy-FabricApplication.ps1 скрипт, предоставляемый шаблоном проекта Service Fabric внутри . Этот скрипт анализирует!--29--> PublishProfile и развертывает ваш кластер service fabric.

Так вы определяет ценности права как PublishProfiles/Cloud.xml и ApplicationParameters/Cloud.xml выполнить скрипт.

он работает, только если у вас есть сертификат, используемый для защиты кластера, установленного на вашем компьютере, конечно. обратите внимание на первую точку '."важно, потому что, если вы не используете его, у вас будет следующая ошибка:

Get-ServiceFabricClusterManifest: экземпляр соединения кластера значение null

см.https://stackoverflow.com/a/38104087/870604

О, и так как есть ошибки на Service Fabric SDK тоже, вы можете отключить свой локальный кластер SF тоже... https://github.com/Azure/service-fabric-issues/issues/821

7. Теперь пришло время для другого обмана.

он просто не работает, служба завершает работу при запуске. После поиска часов внутри LinuxsyslogVer2v0 Azure Таблица хранения (таблица журнала для Linux, расположенная в одной из двух учетных записей хранения Azure, созданных автоматически в кластере SF), я обнаружил, что собственные пакеты NuGet Microsoft также были ошибочными.

в частности, пакет Nuget Microsoft.Azure.Devices не работает на версии 1.6.0. Проблема со ссылкой на dll не найдена или что-то еще. Я откатился к предыдущей версии, а именно 1.5.1, и она была исправлена.

в этот момент у меня не было больше энергии, чтобы создать еще один Github вопрос об этом. Извините, мисс, я не ваша команда QA, я устал.

8. Постройте снова с помощью первого сценария PowerShell, разверните с помощью второго сценария PowerShell, и все готово.

Вы, наконец, развернули надежные службы C#, используя .NET Core 2.0 из Visual Studio (вроде того, как он глючит, и я использовал PowerShell) в Windows в кластер Linux SF.

теперь у меня все еще есть проблемы с моим ASP.NET Core service, но это будет история для другого день.


заключение: TL; DR

весь бардак. Жуки повсюду. В SDK, в инструментах, в некоторых пакетах Microsoft Nuget. Ужасный опыт. Но он поддерживается (в предварительном просмотре), и вы можете заставить его работать. Надеюсь, этот пост поможет...


У меня были похожие проблемы, но я считаю, что это проблема:

в этом выпуске службы .NET Core 2.0 поддерживаются только в Service Fabric для Windows. Полная кросс-платформенная поддержка служб .NET Core 2.0 В Windows и Linux в ближайшее время.

с Примечания К Выпуску Service Fabric 6.1 Таким образом, нет Linux, пока вы ориентируетесь на .net core 2.0.


Я успешно развернуть на Linux ткани с помощью

открыть все службы .csproj файлы и обновить RuntimeIdentifier, как показано ниже

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
</PropertyGroup>

обновить ServiceManifest.xml для удаления .exe расширение, как показано ниже

<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>Web1</Program>
</ExeHost>
</EntryPoint>
</CodePackage>

см https://blogs.msdn.microsoft.com/premier_developer/2018/05/27/running-net-core-2-0-applications-in-a-linux-service-fabric-cluster-on-azure/

* Visual Studio 15.7.3