サービス スタートアップ スクリプトをローカル ユーザー アカウントまたはローカル システム アカウントとして実行する

Service Fabric サービス実行可能ファイルを開始する前に、構成またはセットアップ作業が必要になることがあります。 たとえば、環境変数の構成です。 サービスのサービス マニフェストでは、サービス実行可能ファイルが開始される前に実行するスクリプトを指定できます。 セットアップ実行可能ファイルの実行アカウントは、サービス セットアップ エントリ ポイントの RunAs ポリシーを構成することで変更できます。 個別のセットアップ エントリ ポイントを使用すると、高い権限を持つ構成を短時間実行できるため、サービス ホスト実行可能ファイルは、長時間にわたって高い権限で実行する必要はありません。

セットアップ エントリ ポイント (サービス マニフェストSetupEntryPoint) は特権エントリ ポイントで、既定では、他のエントリポイントの前に、Service Fabric と同じ資格情報で実行されます (通常は NetworkService アカウント)。 EntryPoint によって指定された実行可能ファイルは、通常は実行時間の長いサービス ホストです。 EntryPoint 実行可能ファイルは、SetupEntryPoint 実行可能ファイルが正常に終了した後に実行されます。 結果のプロセスは監視されて再起動され、終了またはクラッシュした場合に、SetupEntryPoint でもう一度開始されます。

サービス セットアップ エントリ ポイントを構成する

SetupEntryPoint サービスで MySetup.bat セットアップ スクリプトを指定する、ステートレス サービスの簡単なサービス マニフェストの例を次に示します。 Arguments は、実行時に引数をスクリプトに渡すときに使用されます。

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

エントリ ポイント セットアップ サービスのポリシーを構成する

既定では、サービス セットアップ エントリ ポイント実行可能ファイルは、Service Fabric と同じ資格情報で実行されます (通常は NetworkService アカウント)。 アプリケーション マニフェストでは、ローカル システム アカウントまたは管理者アカウントで、スタートアップ スクリプトを実行するセキュリティのアクセス許可を変更できます。

ローカル システム アカウントを使用してポリシーを構成する

次のアプリケーション マニフェストの例は、ユーザー管理者アカウント (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>

最初に、SetupAdminUser などのユーザー名で Principals セクションを作成します。 SetupAdminUser ユーザー アカウントは、Administrators システム グループのメンバーです。

次に、ServiceManifestImport セクションで、このプリンシパルを SetupEntryPoint に適用するためのポリシーを構成します。 このポリシーでは、MySetup.bat ファイルは、(管理者特権を持つ) SetupAdminUser として実行する必要があることを Service Fabric に通知します。 メイン エントリ ポイントに対してポリシーを適用 "しない" ため、MyServiceHost.exe のコードは、システム NetworkService アカウントで実行されます。 これはすべてのサービス エントリ ポイントが RunAs で実行する既定のアカウントです。

ローカル システム アカウントを使用してポリシーを構成する

多くの場合、管理者アカウントではなく、ローカル システム アカウントを使用して起動スクリプトを実行することが推奨されます。 管理者グループのメンバーとして RunAs ポリシーを実行すると、コンピューターでユーザー アクセス制御 (UAC) が既定で有効になっているため、通常はうまく動作しません。 このような場合、ローカル ユーザーを管理者グループに追加するのではなく、SetupEntryPoint を LocalSystem として実行することが推奨されます。 次の例では、LocalSystem として実行するように SetupEntryPoint を設定します。

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

Note

Linux クラスターの場合、サービスまたはセットアップ エントリ ポイントをルートとして実行するには、AccountTypeLocalSystem として指定します。

セットアップ エントリ ポイントからスクリプトを実行する

次は、スタートアップ スクリプトをプロジェクトに追加して、管理者特権で実行します。

Visual Studio でサービス プロジェクトを右クリックし、MySetup.bat という名前の新しいファイルを追加します。

次に、サービス パッケージに MySetup.bat ファイルが含まれていることを確認します。 既定では、含まれていません。 ファイルを選択し、右クリックしてコンテキスト メニューを表示し、 [プロパティ] を選択します。 [プロパティ] ダイアログ ボックスで、 [出力ディレクトリにコピー][新しい場合はコピーする] に設定されていることを確認します。 次のスクリーンショットをご覧ください。

SetupEntryPoint バッチ ファイルの Visual Studio CopyToOutput

ここで MySetup.bat ファイルを編集し、次のコマンドを追加して、システム環境変数を設定します。また、テキスト ファイルを出力します。

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

次に、ソリューションをビルドして、開発用のローカル クラスターにデプロイします。 サービスが開始した後、Service Fabric Explorer で示されるように、MySetup.bat ファイルが成功したことを 2 つの方法で確認できます。 PowerShell コマンド プロンプトを起動し、次を入力します。

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

サービスがデプロイされ、Service Fabric Explorer で開始したノードの名前をメモします。 たとえば、Node 2 です。 次に、アプリケーション インスタンスの作業フォルダーに移動し、 TestVariableの値を示す out.txt ファイルを探します。 たとえば、このサービスが Node 2 にデプロイされた場合は、MyApplicationType の次のパスに移動します。

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

セットアップ エントリ ポイント から PowerShell コマンドを実行する

SetupEntryPoint ポイントから PowerShell を実行するには、PowerShell ファイルを指し示すバッチ ファイルで PowerShell.exe を実行します。 最初に、PowerShell ファイルをサービス プロジェクトに追加します (MySetup.ps1 など)。 このファイルがサービス パッケージにも含まれるように、 [新しい場合はコピーする] プロパティを忘れずに設定します。 次の例では、システム環境変数 TestVariable を設定する PowerShell ファイル MySetup.ps1 を開始するバッチ ファイルを示します。

PowerShell ファイルを開始するための MySetup.bat。

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

PowerShell ファイルで、システム環境変数を設定するために次を追加します。

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

Note

既定では、バッチ ファイルが実行されると、work と呼ばれるアプリケーション フォルダーでファイルを検索します。 この場合、MySetup.bat を実行するときに、アプリケーションの コード パッケージ フォルダーである同じフォルダー内に MySetup.ps1 ファイルを見つける必要があります。 このフォルダーを変更するには、次の作業フォルダーを設定します。

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

コンソール リダイレクトを使用してローカルでスタートアップ スクリプトをデバッグする

場合によっては、デバッグ目的でセットアップ スクリプトの実行結果をコンソールに出力し、確認すると便利です。 サービス マニフェストのセットアップ エントリ ポイントでは、コンソール リダイレクト ポリシーを設定できます。これにより出力がファイルに書き込まれます。 ファイル出力はアプリケーションがデプロイおよび実行されるクラスター ノード上の log と呼ばれるアプリケーション フォルダーに書き込まれ、C:\SfDeployCluster\_App\{application-name}\log にあります。 パスにアプリケーション名の後に番号が表示される場合があります。 この数は、デプロイごとに増分されます。 ログ フォルダーに書き込まれるファイルには、標準エラー出力である Code_{service-name}Pkg_S_0.err と、標準出力である Code_{service-name}Pkg_S_0.out が含まれます。 サービスのアクティブ化の試行に応じて、複数のファイルセットが表示される場合があります。

警告

アプリケーションのフェールオーバーに影響する可能性があるため、運用環境でデプロイされたアプリケーションのコンソール リダイレクト ポリシーは決して使用しないでください。 これは、ローカル デプロイおよびデバッグの目的のため "だけ" に使用します。

次のサービス マニフェストの例は、FileRetentionCount 値を使用したコンソール リダイレクトの設定を示しています。

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

ここで Echo コマンドを書き込むように、MySetup.ps1 ファイルを変更すると、これはデバッグのために出力ファイルに書き込みます。

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

警告

自分のスクリプトをデバッグしたら、すぐにこのコンソール リダイレクト ポリシーを削除してください。

次のステップ