从Visual Studio到Linux部署C#状态服务结构应用程序 [英] Deploy a C# Stateful Service Fabric application from Visual Studio to Linux

查看:253
本文介绍了从Visual Studio到Linux部署C#状态服务结构应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

修改18年4月6日=>更新了问题的最新状态


因此,我具有当前正在运行在Azure上的Windows Service Fabric群集上运行的.Net 4.6状态服务.

从09/2017开始,我应该能够使用Linux:

  • 在我的开发机上,我已经修改了两个包含状态服务的csproj项目,因此它们可以作为Windows可执行文件在本地运行.我使用了 win7-x64 runtimeIdentifier.
  • 可以在Windows计算机上本地运行SF群集.

    1. 然后,我对Linux的以前的csproj文件进行了一些更改.我使用了 ubuntu.16.10-x64 runtimeIdentifier.

    我还更改了ServiceManifest.xml文件以使其与Linux兼容的二进制文件为目标:

      <!-- 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. 然后,我已经成功地从Visual Studio部署到我的安全SF Linux群集中.不幸的是,我的两个有状态服务都出现以下错误:

    错误事件:SourceId ='System.Hosting', Property ='CodePackageActivation:Code:EntryPoint'.有一个错误 在激活CodePackage期间.服务主机因退出而终止 代码:134

    看起来像我的二进制文件在启动时崩溃了.所以这是我的问题:

    • 从Visual Studio到Linux上部署C#.Net Core SF状态服务的方法正确吗?

    编辑:在LinuxsyslogVer2v0表内部,出现以下错误:

    starthost.sh [100041]:未处理的异常: System.IO.FileLoadException:无法加载文件或程序集 'System.Threading.Thread,版本= 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端口应该没问题.

    解决方案

    因此,要使其正常工作,实在是一件痛苦的事情.但这行得通.好吧.


    首先,可靠服务仍在Linux上进行预览: https://github.com/Microsoft/service-fabric/issues/71

    对Linux的完全支持应该很快就会出现(实际上,根据先前的链接,它应该已经已经可用了.)

    现在要获取有关如何进行操作的详细信息,这里有一些信息可以帮助其他人,因为Microsoft文档上对此一无所知,而我实际上却花了3天的时间才能使其正常工作.

    1.请为您的项目使用.NET Core 2.0.

    在Linux上受支持.目前处于预览状态,但可以使用.

    2.为您的项目使用正确的RID.

    截至今天(2018年4月),使用的正确RID是ubuntu.16.04-x64. 编辑您的Reliable Service项目的csproj文件,并按如下所示设置RID:

    <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>
    

    有趣的是,您应该能够使用RuntimeIdentifiers参数(最后带有 S )来提供多个RID,如下所示:

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

    因此,您可以同时构建Windows二进制文件和Linux二进制文件. 但是它根本不起作用.从Visual Studio构建项目时,我只能得到以下目录:

    bin/Debug/netcoreapp2.0/
    

    仅DLL,没有有效的入口点.没有win7-x64文件夹,没有ubuntu.16.04-x64,什么也没有. 这是一个应该修复的错误,但不是(我今天使用的都是最新的Visual Studio 15.6.2).参见 https://github.com/dotnet/core/issues/1039

    3.您需要一个有效的服务入口点.

    在Windows上,它是一个可执行文件(* .exe).在Linux上不是.我最终得到了Linux C#示例,并复制/粘贴了入口点. https ://docs.microsoft.com/zh-CN/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 [ "${1}" -ne "0" ]; then
        # make our script exit with the right error code.
        exit ${1}
      fi
    }
    
    DIR=`dirname $0`
    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
    

    两者都在PackageRoot文件夹中.我指定了这两个属性,所以Build Action是"Content",而Copy to Output Directory是"Copy always".

    4.不要使用MSBuild !!

    是的,它也应该构建Linux软件包,或者至少看起来如此,因为当您右键单击项目并单击构建"时,MSBuild能够生成以下文件:

    不信任该操作的明显成功,部署该应用程序将无法执行.某些*.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相关的项目,因此您需要自己构建所有内容. 当使用Visual Studio构建sfproj时,上面的脚本产生的内容与MSBuild创建的pkg文件夹相同.它将所有内容复制到解决方案根目录的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
    

    它重用了sfproj项目中Service Fabric项目模板提供的Deploy-FabricApplication.ps1脚本.该脚本解析Cloud.xml PublishProfile并将其部署到您的服务矩阵群集.

    因此,您在PublishProfiles/Cloud.xmlApplicationParameters/Cloud.xml上都指定了权限值,然后执行脚本.

    当然,只有在具有用于保护计算机上安装的群集的证书的情况下,此方法才有效. 请注意第一个点."之所以重要,是因为如果您不使用它,则会出现以下错误:

    Get-ServiceFabricClusterManifest:群集连接实例为空

    请参见 https://stackoverflow.com/a/38104087/870604

    哦,由于Service Fabric SDK上也有错误,因此您可能也想关闭本地SF群集... https://github.com/Azure/service-fabric-issues/issues/821

    7.现在是另一个欺骗的时候了.

    它根本不起作用,服务在启动时崩溃.在LinuxsyslogVer2v0 Azure存储表(Linux的日志表,位于由SF群集自动创建的两个Azure存储帐户之一)中搜索了几个小时后,我发现Microsoft自己的Nuget软件包也存在问题.

    具体来说,Nuget软件包Microsoft.Azure.Devices在版本1.6.0上不起作用.找不到与dll的引用有关的问题或其他问题.我回滚到以前的版本1.5.1,并已修复.

    在这一点上,我再也没有能力为此提出另一个Github问题了.抱歉,MS,我不是您的质量检查小组,我已经累了.

    8.再次使用第一个PowerShell脚本进行构建,使用第二个PowerShell脚本进行部署,就完成了.

    您终于在Windows上使用Visual Studio中的.NET Core 2.0(有点像是虫子,我使用PowerShell)在Windows SF群集上部署了C#可靠服务.

    现在我的ASP.NET Core服务仍然有问题,但这将是另一回事.


    结论:TL; DR

    整个事情一团糟.到处都是虫子.在SDK中,在工具中,在某些Microsoft Nuget程序包中.糟糕的经验.但是它受支持(目前处于预览状态),您可以使其正常运行.希望这篇文章对您有帮助...

    EDIT 04/06/18 => Updated question with last status


    So I have this working .Net 4.6 Stateful Service that currently run on my Windows Service Fabric cluster deployed on Azure.

    Starting from 09/2017, I should be able to move to Linux: https://blogs.msdn.microsoft.com/azureservicefabric/2017/09/25/service-fabric-6-0-release/

    So I'm trying to deploy it on Linux so I can save costs.

    1. First things first, I've migrated all my code from .Net 4.6 to .Net Core 2.0. Now I can compile my binaries without issues. I've basically created new .Net Core projects and then moved all my source code from .Net 4.6 projects to the new .Net Core ones.

    2. Then I've updated my Service Fabric application. I removed my previous SF services from my sfproj, then I've added my new .Net Core ones.

    Looks like there is a warning (nothing on the output window though), but it's here anyway if I try to create a new empty Statful service using .Net core 2.0 through the template provided by Service Fabric Tools 2.0 (beta):

    So I'm going to live with it.

    1. On my dev machine, I've modified the 2 csproj projects that contain my Stateful services so they can run locally as Windows executables. I've used the win7-x64 runtimeIdentifier.

    Running my SF cluster locally on my Windows machine is fine.

    1. Then I've slightly changed the previous csproj files for Linux. I used the ubuntu.16.10-x64 runtimeIdentifier.

    Also I've changed the ServiceManifest.xml file to target the linux-compatible 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 is a basic script that eventually executes:

    dotnet $DIR/MyService.dll
    

    1. Then I've successfully deployed to my secured SF Linux cluster from Visual Studio. Unfortunately I have the following errors for both my stateful services:

    Error event: SourceId='System.Hosting', Property='CodePackageActivation:Code:EntryPoint'. There was an error during CodePackage activation.The service host terminated with exit code:134

    Looks like my binary crashes when starting. So here are my questions:

    • Is the approach right to deploy a C# .Net Core SF stateful service on Linux from Visual Studio?

    EDIT: looking inside the LinuxsyslogVer2v0 table, I get the following error:

    starthost.sh[100041]: Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'System.Threading.Thread, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

    I found the following bug report: https://github.com/dotnet/sdk/issues/1502 Unfortunately, I still get the error without using MSBuild (using dotnet deploy).

    EDIT: further clarification:

    • My boss want me to run on Linux because starting from D1v2 machines, it's half the price compared to Windows machines (no license etc.)
    • My .NET Core 2.0 services successfully run on Windows. So the .NET Core port should be fine.

    解决方案

    So, this was a real pain in the ass to get it working properly. But it works. Well, kind of.


    First, Reliable Services are still in preview on Linux: https://github.com/Microsoft/service-fabric/issues/71

    Full Linux support should come very soon (actually it should be available already according to the previous link...).

    Now for the details about how to procede, here is some information to help others, because there is just nothing about that on Microsoft documentation and I literally lost 3 days trying to make it work.

    1. Do use .NET Core 2.0 for your projects.

    It is supported on Linux. On preview for now, but it works.

    2. Do use the right RID for your projects.

    As of today (April 2018), the right RID to use is ubuntu.16.04-x64. Edit the csproj files of your Reliable Service projects and set the RID like this:

    <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>
    

    The fun part is, you should be able to provide multiple RIDs using the RuntimeIdentifiers parameter (with a S at the end) like that:

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

    So you could build Windows binaries and Linux binaries at the same time. But it simply doesn't work. When building the project from Visual Studio, I end up with the following directory only:

    bin/Debug/netcoreapp2.0/
    

    Only DLLs, no valid entry point. No win7-x64 folder, no ubuntu.16.04-x64, no nothing. This is a bug, supposed to be fixed, but it's not (I use Visual Studio 15.6.2 all up-to-date as of today). See https://github.com/dotnet/core/issues/1039

    3. You need a valid Entry Point for your service.

    On Windows it's an executable file (*.exe). On Linux it's not. I ended up getting the Linux C# example and copied/pasted the entry point. https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-create-your-first-linux-application-with-csharp

    So basically I now have on my ServiceManifest.xml file of each Reliable Service the following 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 is as follows:

    #!/usr/bin/env bash
    check_errs()
    {
      # Function. Parameter 1 is the return code
      if [ "${1}" -ne "0" ]; then
        # make our script exit with the right error code.
        exit ${1}
      fi
    }
    
    DIR=`dirname $0`
    echo 0x3f > /proc/self/coredump_filter
    source $DIR/dotnet-include.sh
    dotnet $DIR/NAME_OF_YOUR_SERVICE_DLL.dll $@
    check_errs $?
    

    dotnet-include.sh is as follows:

    #!/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
    

    Both are inside the PackageRoot folder. I specified for both their properties so the Build Action is "Content" and the Copy to Output Directory is "Copy always".

    4. Do NOT build using MSBuild !!

    Yeah it is supposed to build Linux packages too, or at least it seems so, because MSBuild is able to produce the following files when you right click on your project and click "Build":

    Don't trust the apparent success of the operation, it will miserably FAIL to properly execute when deployed. Some *.so files missing and other issues. MSBuild is buggy as hell and misbehaves regarding dependencies.

    See for instance this bug report: https://github.com/dotnet/sdk/issues/1502 Still not fixed after almost a year...

    Or https://github.com/dotnet/core/issues/977 (got this one, too).

    5. Do write some PowerShell script to build the stuff by yourself.

    I ended up reinventing the wheel using the following script to build my package:

    # 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 file is a Visual Studio / MSBuild related project, so you need to build everything by yourself. The script above produces the same content as the pkg folder created by MSBuild when building your sfproj using Visual Studio. It copies everything on a PKG folder at the root of your solution.

    The package structure is detailed here: https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/service-fabric/service-fabric-package-apps.md

    6. Now it's time to deploy!

    At this point I didn't trusted Visual Studio anymore, so I built my own PowerShell script:

    . .\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
    

    It reuses the Deploy-FabricApplication.ps1 script provided by the Service Fabric project template inside the sfproj project. This script parses the Cloud.xml PublishProfile and deploys to your service fabric cluster.

    So you specifies the rights values on both PublishProfiles/Cloud.xml and ApplicationParameters/Cloud.xml then execute the script.

    It only works if you have the certificate used to secure the cluster installed on your machine, of course. Do note the first dot '.' is important, because if you don't use it, you'll have the following error:

    Get-ServiceFabricClusterManifest : Cluster connection instance is null

    See https://stackoverflow.com/a/38104087/870604

    Oh, and as there are bugs on the Service Fabric SDK too, you might want to shutdown your local SF cluster too... https://github.com/Azure/service-fabric-issues/issues/821

    7. Now it's time for another deception.

    It simply doesn't work, the service crashes on startup. After searching hours inside the LinuxsyslogVer2v0 Azure Storage table (the log table for Linux, located in one of the two Azure Storage Accounts created automatically with the SF cluster), I found that Microsoft own Nuget Packages were buggy too.

    Specifically, the Nuget package Microsoft.Azure.Devices doesn't work on version 1.6.0. An issue with a reference of a dll not found or whatever. I rollbacked to a previous version, namely 1.5.1, and it was fixed.

    At this point I didn't had anymore energy to create another Github issue about that. Sorry MS, I'm not your QA team, I'm getting tired.

    8. Build again using the first PowerShell script, deploy using the second PowerShell script, and you're done.

    You've finally deployed C# Reliable Services using .NET Core 2.0 from Visual Studio (kind of, as it's buggy and I used PowerShell) on Windows to a Linux SF Cluster.

    Now I still have issues with my ASP.NET Core service, but it will be a story for another day.


    Conclusion: TL;DR

    The whole thing is a mess. Bugs everywhere. In the SDK, in the tools, in some of Microsoft Nuget Packages. Awful experience. But it is supported (in preview for now) and you can make it work. Hope this post will help...

    这篇关于从Visual Studio到Linux部署C#状态服务结构应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆