Het opstartscript van een service uitvoeren als lokale gebruiker of systeemaccount

Voordat een uitvoerbare Service Fabric-service wordt gestart, kan het nodig zijn om bepaalde configuratie- of installatiewerkzaamheden uit te voeren. Bijvoorbeeld omgevingsvariabelen configureren. U kunt een script opgeven dat moet worden uitgevoerd voordat het uitvoerbare bestand van de service wordt gestart in het servicemanifest voor de service. Door een RunAs-beleid te configureren voor het ingangspunt voor het instellen van de service, kunt u wijzigen onder welk account het uitvoerbare installatiebestand wordt uitgevoerd. Met een afzonderlijk invoerpunt voor de installatie kunt u configuratie met hoge bevoegdheden gedurende een korte periode uitvoeren, zodat het uitvoerbare bestand van de servicehost gedurende langere tijd niet met hoge bevoegdheden hoeft te worden uitgevoerd.

Het invoerpunt voor de installatie (SetupEntryPoint in het servicemanifest) is een bevoegd toegangspunt dat standaard wordt uitgevoerd met dezelfde referenties als Service Fabric (meestal het NetworkService-account ) vóór een ander toegangspunt. Het uitvoerbare bestand dat is opgegeven door EntryPoint , is doorgaans de langlopende servicehost. Het uitvoerbare bestand EntryPoint wordt uitgevoerd nadat het uitvoerbare bestand SetupEntryPoint is afgesloten. Het resulterende proces wordt bewaakt en opnieuw gestart en begint opnieuw met SetupEntryPoint als het ooit wordt beëindigd of vastloopt.

Het toegangspunt voor service-instellingen configureren

Hier volgt een eenvoudig voorbeeld van een servicemanifest voor een staatloze service die een installatiescript opgeeftMySetup.bat in de service SetupEntryPoint. Argumenten worden gebruikt om argumenten door te geven aan het script wanneer het wordt uitgevoerd.

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="MyStatelessServicePkg"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="https://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <Description>An example service manifest.</Description>
  <ServiceTypes>
    <StatelessServiceType ServiceTypeName="MyStatelessServiceType" />
  </ServiceTypes>

  <!-- Code package is your service executable. -->
  <CodePackage Name="Code" Version="1.0.0">
    <SetupEntryPoint>
      <ExeHost>
        <Program>MySetup.bat</Program>
        <Arguments>MyValue</Arguments>
        <WorkingFolder>Work</WorkingFolder>        
      </ExeHost>
    </SetupEntryPoint>
    <EntryPoint>
      <ExeHost>
        <Program>MyStatelessService.exe</Program>
      </ExeHost>
    </EntryPoint>
  </CodePackage>

  <ConfigPackage Name="Config" Version="1.0.0" />

  <Resources>
    <Endpoints>
      <Endpoint Name="ServiceEndpoint" />
    </Endpoints>
  </Resources>
</ServiceManifest>

Het beleid configureren voor een service-instellingsinvoerpunt

Standaard wordt het uitvoerbare invoerpunt van de service-installatie uitgevoerd onder dezelfde referenties als Service Fabric (meestal het NetworkService-account ). In het toepassingsmanifest kunt u de beveiligingsmachtigingen wijzigen om het opstartscript uit te voeren onder een lokaal systeemaccount of een beheerdersaccount.

Het beleid configureren met behulp van een lokaal systeemaccount

In het volgende voorbeeld van het toepassingsmanifest ziet u hoe u het ingangspunt voor het instellen van de service configureert voor uitvoering onder een gebruikersbeheerdersaccount (SetupAdminUser).

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="MyApplicationType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Parameters>
    <Parameter Name="MyStatelessService_InstanceCount" DefaultValue="-1" />
  </Parameters>
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="MyStatelessServicePkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides />
    <Policies>
      <RunAsPolicy CodePackageRef="Code" UserRef="SetupAdminUser" EntryPointType="Setup" />
    </Policies>
  </ServiceManifestImport>
  <DefaultServices>
    <Service Name="MyStatelessService" ServicePackageActivationMode="ExclusiveProcess">
      <StatelessService ServiceTypeName="MyStatelessServiceType" InstanceCount="[MyStatelessService_InstanceCount]">
        <SingletonPartition />
      </StatelessService>
    </Service>
  </DefaultServices>
  <Principals>
    <Users>
      <User Name="SetupAdminUser">
        <MemberOf>
          <SystemGroup Name="Administrators" />
        </MemberOf>
      </User>
    </Users>
  </Principals>
</ApplicationManifest>

Maak eerst een sectie Principals met een gebruikersnaam, zoals SetupAdminUser. Het gebruikersaccount SetupAdminUser is lid van de systeemgroep Administrators.

Configureer vervolgens in de sectie ServiceManifestImport een beleid om deze principal toe te passen op SetupEntryPoint. Dit beleid vertelt Service Fabric dat wanneer het MySetup.bat-bestand wordt uitgevoerd, het moet worden uitgevoerd als SetupAdminUser (met beheerdersbevoegdheden). Omdat u geen beleid hebt toegepast op het hoofdinvoerpunt, wordt de code in MyServiceHost.exe uitgevoerd onder het netwerkserviceaccount van het systeem. Dit is het standaardaccount waarop alle service-toegangspunten worden uitgevoerd.

Het beleid configureren met behulp van lokale systeemaccounts

Vaak is het beter om het opstartscript uit te voeren met een lokaal systeemaccount in plaats van een beheerdersaccount. Het uitvoeren van het RunAs-beleid als lid van de groep Administrators werkt meestal niet goed omdat op computers gebruikers Access Control (UAC) standaard is ingeschakeld. In dergelijke gevallen wordt het aanbevolen om SetupEntryPoint uit te voeren als LocalSystem, in plaats van als een lokale gebruiker die is toegevoegd aan de groep Administrators. In het volgende voorbeeld ziet u het instellen van SetupEntryPoint om uit te voeren als LocalSystem:

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="MyApplicationType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Parameters>
    <Parameter Name="MyStatelessService_InstanceCount" DefaultValue="-1" />
  </Parameters>
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="MyStatelessServicePkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides />
    <Policies>
         <RunAsPolicy CodePackageRef="Code" UserRef="SetupLocalSystem" EntryPointType="Setup" />
      </Policies>
  </ServiceManifestImport>
  <DefaultServices>
    <Service Name="MyStatelessService" ServicePackageActivationMode="ExclusiveProcess">
      <StatelessService ServiceTypeName="MyStatelessServiceType" InstanceCount="[MyStatelessService_InstanceCount]">
        <SingletonPartition />
      </StatelessService>
    </Service>
  </DefaultServices>
  <Principals>
      <Users>
         <User Name="SetupLocalSystem" AccountType="LocalSystem" />
      </Users>
   </Principals>
</ApplicationManifest>

Notitie

Als u voor Linux-clusters een service of het installatie-invoerpunt als hoofdmap wilt uitvoeren, kunt u het AccountType opgeven als LocalSystem.

Een script uitvoeren vanaf het invoerpunt voor de installatie

Voeg nu een opstartscript toe aan het project om uit te voeren onder beheerdersbevoegdheden.

Klik in Visual Studio met de rechtermuisknop op het serviceproject en voeg een nieuw bestand toe met de naamMySetup.bat.

Controleer vervolgens of het MySetup.bat-bestand is opgenomen in het servicepakket. Standaard is dit niet het. Selecteer het bestand, klik met de rechtermuisknop om het contextmenu weer te geven en kies Eigenschappen. Controleer in het dialoogvenster Eigenschappen of Kopiëren naar uitvoermap is ingesteld op Kopiëren indien nieuwer. Zie de volgende schermafbeelding.

Visual Studio CopyToOutput voor SetupEntryPoint-batchbestand

Bewerk nu het MySetup.bat-bestand en voeg de volgende opdrachten toe om een systeemomgevingsvariabele in te stellen en een tekstbestand uit te voeren:

REM Set a system environment variable. This requires administrator privilege
setx -m TestVariable %*
echo System TestVariable set to > out.txt
echo %TestVariable% >> out.txt

REM To delete this system variable us
REM REG delete "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v TestVariable /f

Vervolgens bouwt en implementeert u de oplossing in een lokaal ontwikkelcluster. Nadat de service is gestart, zoals wordt weergegeven in Service Fabric Explorer, kunt u zien dat het MySetup.bat-bestand op twee manieren is geslaagd. Open een PowerShell-opdrachtprompt en typ:

PS C:\ [Environment]::GetEnvironmentVariable("TestVariable","Machine")
MyValue

Noteer vervolgens de naam van het knooppunt waar de service is geïmplementeerd en gestart in Service Fabric Explorer. Bijvoorbeeld Node 2. Navigeer vervolgens naar de werkmap van het toepassingsexemplaren om het out.txt-bestand te vinden waarin de waarde van TestVariable wordt weergegeven. Als deze service bijvoorbeeld is geïmplementeerd in Knooppunt 2, kunt u naar dit pad gaan voor het MyApplicationType:

C:\SfDevCluster\Data\_App\Node.2\MyApplicationType_App\work\out.txt

PowerShell-opdrachten uitvoeren vanaf een installatie-invoerpunt

Als u PowerShell wilt uitvoeren vanaf het Punt SetupEntryPoint , kunt u PowerShell.exe uitvoeren in een batchbestand dat naar een PowerShell-bestand verwijst. Voeg eerst een PowerShell-bestand toe aan het serviceproject, bijvoorbeeld MySetup.ps1. Vergeet niet om de eigenschap Kopiëren als nieuwer in te stellen, zodat het bestand ook wordt opgenomen in het servicepakket. In het volgende voorbeeld ziet u een batch-voorbeeldbestand waarmee een PowerShell-bestand met de naam MySetup.ps1 wordt gestart. Hiermee wordt een systeemomgevingsvariabele met de naam TestVariable ingesteld.

MySetup.bat om een PowerShell-bestand te starten:

powershell.exe -ExecutionPolicy Bypass -Command ".\MySetup.ps1"

Voeg in het PowerShell-bestand het volgende toe om een systeemomgevingsvariabele in te stellen:

[Environment]::SetEnvironmentVariable("TestVariable", "MyValue", "Machine")
[Environment]::GetEnvironmentVariable("TestVariable","Machine") > out.txt

Notitie

Wanneer het batchbestand wordt uitgevoerd, wordt standaard gekeken naar de toepassingsmap met de naam werk voor bestanden. In dit geval, wanneer MySetup.bat wordt uitgevoerd, willen we dat het MySetup.ps1-bestand zich in dezelfde map bevindt, namelijk de map met het toepassingscodepakket . Als u deze map wilt wijzigen, stelt u de werkmap in:

<SetupEntryPoint>
    <ExeHost>
    <Program>MySetup.bat</Program>
    <WorkingFolder>CodePackage</WorkingFolder>
    </ExeHost>
</SetupEntryPoint>

Lokaal fouten opsporen in een opstartscript met behulp van console-omleiding

Soms is het handig voor foutopsporingsdoeleinden om de console-uitvoer te zien van het uitvoeren van een installatiescript. U kunt een consoleomleidingsbeleid instellen op het invoerpunt van de installatie in het servicemanifest, dat de uitvoer naar een bestand schrijft. De bestandsuitvoer wordt geschreven naar de toepassingsmap met de naam logboek op het clusterknooppunt waar de toepassing wordt geïmplementeerd en uitgevoerd, te vinden in C:\SfDeployCluster\_App\{application-name}\log. Mogelijk ziet u een getal achter de naam van uw toepassing in het pad. Dit aantal wordt verhoogd voor elke implementatie. De bestanden die naar de logboekmap worden geschreven, bevatten Code_{service-name}Pkg_S_0.err, de standaardfoutuitvoer, en Code_{service-name}Pkg_S_0.out, de standaarduitvoer. Mogelijk ziet u meer dan één set bestanden, afhankelijk van de activeringspogingen van de service.

Waarschuwing

Gebruik nooit het consoleomleidingsbeleid in een toepassing die in productie is geïmplementeerd, omdat dit van invloed kan zijn op de toepassingsfailover. Gebruik dit alleen voor lokale ontwikkelings- en foutopsporingsdoeleinden.

In het volgende voorbeeld van het servicemanifest ziet u hoe u de consoleomleiding instelt met een FileRetentionCount-waarde:

<SetupEntryPoint>
    <ExeHost>
    <Program>MySetup.bat</Program>
    <WorkingFolder>CodePackage</WorkingFolder>
    <ConsoleRedirection FileRetentionCount="10"/>
    </ExeHost>
</SetupEntryPoint>

Als u nu het MySetup.ps1-bestand wijzigt om een Echo-opdracht te schrijven, wordt er naar het uitvoerbestand geschreven voor foutopsporing:

Echo "Test console redirection which writes to the application log folder on the node that the application is deployed to"

Waarschuwing

Nadat u fouten in uw script hebt opgespoord, verwijdert u dit consoleomleidingsbeleid onmiddellijk.

Volgende stappen