Delen via


Het opstartscript van een service uitvoeren als lokale gebruiker of systeemaccount

Voordat het uitvoerbare bestand van een Service Fabric-service wordt gestart, kan het nodig zijn om enige configuratie- of installatiewerkzaamheden uit te voeren. Bijvoorbeeld het configureren van omgevingsvariabelen. 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 invoerpunt van de service-installatie, kunt u wijzigen onder welk account het uitvoerbare installatieprogramma wordt uitgevoerd. Met een afzonderlijk installatieinvoerpunt kunt u een 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 installatieinvoerpunt (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 installatieprogramma 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 servicemanifest voor een staatloze service die een installatiescript opgeeft MySetup.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 voor een service-installatiepunt configureren

Standaard wordt het uitvoerbare invoerpunt voor 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 invoerpunt voor de service-installatie configureert dat moet worden uitgevoerd onder het 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 groep Administrators.

Configureer vervolgens onder 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 dat alle service-toegangspunten worden uitgevoerd als.

Het beleid configureren met behulp van lokale systeemaccounts

Vaak is het beter om het opstartscript uit te voeren met behulp van een lokaal systeemaccount in plaats van een beheerdersaccount. Het uitvoeren van het RunAs-beleid als lid van de groep Administrators werkt doorgaans niet goed omdat op computers gebruikerstoegangsbeheer (UAC) standaard is ingeschakeld. In dergelijke gevallen wordt aanbevolen om SetupEntryPoint als LocalSystem uit te voeren in plaats van als een lokale gebruiker die is toegevoegd aan de groep Administrators. In het volgende voorbeeld ziet u hoe u SetupEntryPoint instelt 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 installatieinvoerpunt als hoofdmap wilt uitvoeren, kunt u het AccountType opgeven als LocalSystem.

Een script uitvoeren vanaf het invoerpunt van 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 naam MySetup.bat.

Controleer vervolgens of het MySetup.bat-bestand is opgenomen in het servicepakket. Het is standaard niet. Selecteer het bestand, klik met de rechtermuisknop om het snelmenu op te halen en kies Eigenschappen. Controleer in het dialoogvenster Eigenschappen of Kopiëren naar Uitvoermap is ingesteld op Kopiëren als nieuwer. Zie de volgende schermopname.

Visual Studio CopyToOutput voor Het batchbestand SetupEntryPoint

Bewerk nu het MySetup.bat-bestand en voeg de volgende opdrachten toe om een omgevingsvariabele voor het systeem 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

Bouw en implementeer vervolgens de oplossing in een lokaal ontwikkelcluster. Nadat de service is gestart, zoals weergegeven in Service Fabric Explorer, kunt u zien dat het bestand MySetup.bat 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 bestand out.txt met de waarde TestVariable weer te geven. Als deze service bijvoorbeeld is geïmplementeerd in Node 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 installatieinvoerpunt

Als u PowerShell wilt uitvoeren vanaf het punt SetupEntryPoint, kunt u PowerShell.exe uitvoeren in een batchbestand dat verwijst naar een PowerShell-bestand. Voeg eerst een PowerShell-bestand toe aan het serviceproject, bijvoorbeeld MySetup.ps1. Vergeet niet om de eigenschap Kopiëren in te stellen als er nieuwere eigenschap is, zodat het bestand ook is opgenomen in het servicepakket. In het volgende voorbeeld ziet u een voorbeeldbatchbestand dat een PowerShell-bestand start met de naam MySetup.ps1, waarmee een omgevingsvariabele van het systeem wordt ingesteld met de naam TestVariable.

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 omgevingsvariabele voor het systeem in te stellen:

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

Notitie

Wanneer het batchbestand wordt uitgevoerd, kijkt het standaard naar de toepassingsmap met de naam Werk voor bestanden. In dit geval, wanneer MySetup.bat wordt uitgevoerd, willen we dat het bestand MySetup.ps1 zich in dezelfde map bevindt. Dit is 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>

Fouten in een opstartscript lokaal opsporen met behulp van consoleomleiding

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

Waarschuwing

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

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

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

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

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