Windows 認証を使用する ASP.NET アプリを GKE Windows コンテナにデプロイする

このチュートリアルでは、統合 Windows 認証で IIS を使用する ASP.NET ウェブ アプリケーションを作成する方法と、そのアプリケーションを、ドメイン参加した Windows Server ノードがある Google Kubernetes Engine(GKE)クラスタに、Windows コンテナを使用してデプロイする方法を説明します。この構成は、アプリケーションが他の Windows リソースを認証できるように、Google Cloud 上の Windows コンテナに ASP.NET アプリケーションをデプロイする場合に活用できます。また、Active Directory にグループ マネージド サービス アカウント(gMSA)を作成する方法と、GKE でウェブ アプリケーションのデプロイを構成して使用する方法についても説明します。

このチュートリアルは、システム管理者を対象としています。Active Directory の知識を十分に持ち、Google Kubernetes Engine(GKE)の使用経験があることを前提としています。

目標

  • ドメイン参加した Windows Server ノードがある GKE クラスタを作成し、Active Directory gMSA をサポートするようにクラスタを構成します。
  • 統合 Windows 認証で IIS を使用する ASP.NET ウェブ アプリケーション コンテナ イメージをビルドしてデプロイします。

料金

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。新しい Google Cloud ユーザーは無料トライアルをご利用いただけます。

始める前に

  1. VM が自動的にドメインに参加するように Active Directory を構成するのチュートリアルの手順に沿って、Active Directory ドメイン参加用の Cloud Run サービスを作成します。

  2. このチュートリアルを、自動ドメイン参加をテストする VM を作成したプロジェクトとは別の Google Cloud プロジェクトで実行する場合は、Cloud プロジェクトでプロジェクトの自動ドメイン参加を有効にする手順を行います。

    上記のチュートリアルを完了すると、新しい Cloud Run サービスが作成され、その URL が PowerShell ウィンドウ($RegisterUrl 変数の値)に出力されます。この URL は、このチュートリアルで使用するためメモしておきます。

  3. Compute Engine API、Google Kubernetes Engine API、Cloud Build API、Container Registry API、Resource Manager API が有効になっていることを確認します。

    API を有効にする

    このチュートリアルを完了した後、作成したリソースを削除すると、それ以上の請求は発生しません。詳しくは、クリーンアップをご覧ください。

はじめに

ドメイン参加した Windows Server で実行される Windows ベースのアプリケーションは、多くの場合、ユーザーとアプリケーションの認証に Microsoft Active Directory(AD)の ID を使用します。この一般的なユースケースは、次のとおりです。

  • 統合 Windows 認証を使用する ASP.NET ウェブ アプリケーションを作成して、Active Directory ユーザーがウェブ アプリケーションへログインするときに認証する。
  • サーバーの Active Directory コンピュータ アカウントを使用して、リモートの SMB 共有やリモート Microsoft SQL Server インスタンスなどのリソースに、ネットワーク経由でアクセスするアプリケーションを作成する。

Windows コンテナは、ドメインに参加できないため、Active Directory にコンピュータ アカウントがありません。このため、Windows コンテナで実行される ASP.NET ウェブ アプリケーションは、統合 Windows 認証を使用して Active Directory ユーザーを認証できず、ネットワーク内の保護されたリソースにもアクセスできません。ASP.NET がセキュアなリソースにアクセスする方法の詳細については、Microsoft のドキュメントのアプリケーション プール ID をご覧ください。

Windows コンテナは、コンピュータ アカウントではなく Active Directory グループ マネージド サービス アカウント(gMSA)の ID を使用して、Active Directory と、ネットワーク内にある保護された他のリソース(ファイル共有や SQL Server インスタンスなど)にアクセスできます。詳細については、Microsoft のドキュメントのグループ マネージド サービス アカウントの概要をご覧ください。

次のアーキテクチャ図では、このチュートリアルで使用するリソースを示します。

Active Domain のドメインに参加した GKE 上の Windows Server コンテナ。

この図には、次の要素が描かれています。

  • 開発用 VM。このチュートリアルでは、ASP.NET ウェブ アプリケーション コンテナ イメージのビルドと gMSA の作成に使用する Windows VM を作成します。
  • GKE クラスタとノード。このチュートリアルの GKE クラスタには、次のように使用する Linux ノードプールと Windows Server ノードプールがあります。
    • Linux ノードでは、Linux オペレーティング システムのみで動作するシステム コンポーネント(GKE 指標サーバーなど)を実行します。
    • Windows Server ノードでは、Windows Server コンテナをホストするために使用され、Active Directory ドメインに追加されます。
  • Active Directory のインフラストラクチャ。GKE Windows ノードをドメイン参加させるには、まず VM が自動的にドメインに参加するように Active Directory を構成するチュートリアルを実行します。そのチュートリアルでは、Active Directory に新しいコンピュータ(インスタンス)を登録して、インスタンスがドメインへの参加処理を行うために使用する一時パスワードを発行する Cloud Run サービスを作成します。Windows Server ノードプール内の新しいインスタンスは、その Cloud Run サービスを呼び出して Active Directory ドメインに参加します。
  • ネットワーク ロードバランサ。オンプレミス ユーザーがブラウザを開いて、ASP.NET ウェブ アプリケーションを参照すると、トラフィックはネットワーク ロードバランサを通過します。ロードバランサは、ウェブ アプリケーション用に GKE LoadBalancer Service を作成する際に、GKE によって作成されます。また、ユーザーは、Active Directory の認証情報をウェブ アプリケーションに渡すことで、ウェブ アプリケーションに対する認証も行います。

インフラストラクチャの作成

関連チュートリアルを完了したら、このチュートリアルのインフラストラクチャ コンポーネントを作成します。そのコンポーネントは、次のとおりです。

  • ASP.NET ウェブ アプリケーションのコンテナ イメージを含む Windows Server VM。
  • Windows Server ノードプールがある GKE クラスタ。
  • GKE Pod に Active Directory へのアクセスを許可するファイアウォール ルール。
  • デプロイメント内の gMSA リソースの構成と入力を扱う GKE クラスタ内の Webhook。

開発用 VM を作成する

作成する Windows Server コンテナ イメージは、コンテナ イメージをビルドする VM の Windows Server バージョンと一致する必要があります。このバージョンは、GKE Windows Server ノードの Windows Server バージョンとも一致する必要があります。バージョンが異なる Windows Server で、コンテナ イメージを作成するとエラーが発生します。コンテナの実行でも同様にエラーとなります。Windows コンテナの互換性要件の詳細については、コンテナホストのバージョンとコンテナ イメージのバージョンを一致させるをご覧ください。

このチュートリアルでは、VM 用 Windows Server の Long-Term Servicing Channel(LTSC)2019 バージョン、GKE の Windows Server ノード、コンテナ イメージを使用します。詳細については、Windows Server バージョンと GKE バージョンの間のバージョン マッピングをご覧ください。

  1. Cloud Console で、Cloud Shell をアクティブにします。

    Cloud Shell をアクティブにする

    Cloud Console の下部にある Cloud Shell セッションが開始し、コマンドライン プロンプトが表示されます。Cloud Shell はシェル環境です。gcloud コマンドライン ツールなどの Cloud SDK がすでにインストールされており、現在のプロジェクトの値もすでに設定されています。セッションが初期化されるまで数秒かかることがあります。

  2. PowerShell が開いている場合は、「exit」と入力して終了します。
  3. ネットワークの名前、サブネットワークの名前、Active Directory サービス URL を、各環境変数に設定します。

    export NETWORK_NAME=NETWORK-NAME
    export SUBNETWORK_NAME=SUBNETWORK-NAME
    export AD_JOIN_SERVICE_URL=AD-JOIN-SERVICE-URL
    

    以下を置き換えます。

    • NETWORK-NAME: VM をデプロイする VPC ネットワーク。
    • SUBNETWORK-NAME: VM をデプロイするサブネット。
    • AD-JOIN-SERVICE-URL: 始める前にセクションでデプロイした Cloud Run サービスの URL。
  4. 現在の環境の Google Cloud プロジェクト ID とリージョンを設定します。

    gcloud config set project PROJECT-ID
    gcloud config set compute/zone ZONE-NAME
    

    以下を置き換えます。

    • PROJECT-ID: Google Cloud プロジェクト ID。
    • ZONE-NAME: すべての VM をデプロイするゾーン。レイテンシを短くするには、Active Directory のドメインに参加した Cloud Run サービスをデプロイしたリージョン内のゾーンを選択することをおすすめします。
  5. 開発用 VM のサービス アカウントを作成します。

    export SERVICE_ACCOUNT_NAME=dev-vm
    export SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    
    gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME \
        --display-name="Development VM Service Account"
    
  6. サービス アカウントに、Container Registry へのアクセス権を付与します。

    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
        --role="roles/storage.admin"
    
    gsutil iam ch serviceAccount:$SERVICE_ACCOUNT_EMAIL:objectAdmin \
        gs://artifacts.$GOOGLE_CLOUD_PROJECT.appspot.com
    
  7. サービス アカウントに GKE へのアクセス権を付与します。

    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
        --role="roles/container.admin"
    

    サービス アカウントに、container.admin ロールが付与されている理由は、このロールには、プロジェクトで GKE クラスタを作成する権限と、ロールベースのアクセス制御(RBAC)リソースを含め、クラスタ内のリソースを管理する権限の両方が備わっているためです。RBAC リソースは、gMSA の使用を許可する Pod を管理するために必要です。

  8. 新しい Windows Server VM を作成します。

    gcloud compute instances create gmsa-dev-vm \
        --image-project windows-cloud \
        --image-family windows-2019-core-for-containers \
        --machine-type n1-standard-2 \
        --boot-disk-type=pd-ssd \
        --boot-disk-size=100GB \
        --network $NETWORK_NAME \
        --subnet $SUBNETWORK_NAME \
        --service-account=$SERVICE_ACCOUNT_EMAIL \
        --scopes https://www.googleapis.com/auth/cloud-platform \
        --metadata sysprep-specialize-script-ps1="iex((New-Object System.Net.WebClient).DownloadString('$AD_JOIN_SERVICE_URL')); Add-WindowsFeature RSAT-AD-PowerShell"
    

    スコープ https://www.googleapis.com/auth/cloud-platform を使用すると、インスタンスのサービス アカウント用に定義された IAM ロールに応じて、インスタンスがすべての Google Cloud APIs にアクセスできるようになります。

    VM は、インターネットと通信できるように外部 IP アドレスが 1 つ付加されて作成されます。VM には、gitkubectl など複数のユーティリティをダウンロードできるように、インターネット アクセスが必要です。また、GitHub から ASP.NET ウェブ アプリケーションもダウンロードします。

    sysprep の段階では、新しいインスタンスが Active Directory ドメインに参加し、ドメイン アカウントを使用してリモートからインスタンスにアクセスできるようになります。また、sysprep コマンドのスクリプトによって、Active Directory の PowerShell モジュールもインストールされます。

GKE クラスタを作成する

  1. Cloud Shell で、GKE クラスタの名前を環境変数に設定します。

    export GKE_CLUSTER_NAME=cluster-1
    
  2. GKE クラスタを作成します。

    gcloud container clusters create $GKE_CLUSTER_NAME \
        --release-channel rapid \
        --network $NETWORK_NAME \
        --subnetwork $SUBNETWORK_NAME \
        --enable-ip-alias
    

    --release-channel パラメータrapid に設定すると、GKE クラスタが最新の Kubernetes バージョンでデプロイされます。--enable-ip-alias パラメータは、エイリアス IP を有効にします。Windows Server ノードにはエイリアス IP が必要です。

GKE で Windows Server ノードプールを作成する

CLI を使用して新しい GKE クラスタを作成すると、そのクラスタは Linux ノードプールを使用して作成されます。GKE で Windows Server を使用するには、Windows Server ノードプールを作成します。

GKE クラスタには、クラスタの内部(システム)コンテナを実行するために、少なくとも 1 つの Linux ノードが必要です。GKE クラスタを Windows Server ノードだけで作成することはできません。

  1. Cloud Shell で、Windows Server ノードプールの名前を環境変数に設定します。

    export NODE_POOL_NAME=windows-server-pool
    
  2. GKE Windows Server ノードプールを作成します。

    gcloud container node-pools create $NODE_POOL_NAME \
        --cluster $GKE_CLUSTER_NAME \
        --machine-type n1-standard-2 \
        --image-type WINDOWS_LTSC \
        --num-nodes 2 \
        --no-enable-autoupgrade \
        --metadata sysprep-specialize-script-ps1="iex((New-Object System.Net.WebClient).DownloadString('$AD_JOIN_SERVICE_URL'))"
    

    sysprep-specialize-script-ps1 メタデータキーは、インスタンスの初回起動前に、GCESysprep のステップで実行される PowerShell スクリプトを指す組み込みキーです。

    iex コマンドレットは、Cloud Run にデプロイした Active Directory ドメイン参加サービスから PowerShell スクリプトをダウンロードします。つづいて、新しいインスタンスを Active Directory ドメインに参加させるスクリプトを実行します。

    --no-enable-autoupgrade パラメータは、プール内のすべてのノードに対してノードの自動アップグレードを無効にします。これは、ノードの Windows イメージをアップグレードすると、ノードの Windows Server バージョンと Pod の Windows Server バージョン間で互換性が失われる可能性があるためです。詳細については、Windows Server ノードプールのアップグレードをご覧ください。

    各ノードが作成されると、domain-join PowerShell スクリプトによってノードがドメインに参加します。

  3. ノードプールが作成されるまで数分待ってから、次のコマンドを実行して、すべてのノードがドメインに参加したことを確認します。

    kubectl get node \
    -l cloud.google.com/gke-nodepool=$NODE_POOL_NAME \
    -o custom-columns=":metadata.name" --no-headers \
        | xargs -I{} gcloud compute instances get-serial-port-output {} --port 1 \
        | grep "sysprep-specialize-script-ps1:.*success" --ignore-case
    

    ノードがドメインに参加している場合、出力は次のようになります。

    timestamp GCEMetadataScripts: sysprep-specialize-script-ps1: Successfully registered computer account.
    timestamp GCEMetadataScripts: sysprep-specialize-script-ps1: Computer successfully joined to domain
    
    Specify --start=152874 in the next get-serial-port-output invocation to get only the new output starting from here.
    

    スクリプトの出力をすべて表示する場合は、grep コマンドから「.*success」を削除します。

GKE Pod に Active Directory へのアクセスを許可する

GKE クラスタの Pod が次のプロトコルを使用してドメイン コントローラにアクセスすることを許可するファイアウォール ルールを作成する必要があります。

  • Kerberos(UDP/88、TCP/88)
  • NTP(UDP/123)
  • RPC(TCP/135、TCP/49152~65535)
  • LDAP(UDP/389、TCP/389)
  • SMB(UDP/445、TCP/445)
  • LDAP GC(TCP/3268)
  • Active Directory Web サービス(TCP/9389)

ルールは、ドメイン コントローラに割り当てたサービス アカウントに基づいて適用するか、このチュートリアルで行うように、ネットワーク タグを使用して適用できます。Active Directory 関連のポートの詳細については、Active Directory のポートとプロトコルの要件およびファイアウォールでの Active Directory の使用のドキュメントをご覧ください。

Managed Service for Microsoft Active Directory(マネージド Microsoft AD)を使用している場合は、この手順を省略できます。

  1. Cloud Shell で、GKE クラスタの Pod IP アドレス範囲を取得します。

    CLUSTER_IP_RANGE=`gcloud container clusters describe cluster-1 --format="value(clusterIpv4Cidr)"`
    
  2. GKE Pod から Active Directory へのアクセスを許可するファイアウォール ルールを作成します。

    gcloud compute firewall-rules create allow-gke-pods-to-ad \
        --network $NETWORK_NAME \
        --allow udp:88,tcp:88,udp:123,tcp:135,tcp:49152-65535,udp:389,tcp:389,udp:445,tcp:445,tcp:3268,tcp:9389 \
        --source-ranges=$CLUSTER_IP_RANGE \
        --target-tags DC-TAG
    

    DC-TAG は、ドメイン コントローラの VM に割り当てられているネットワーク タグに置き換えます。

gMSA の使用をサポートするように GKE を構成する

Windows Server ノードで gMSA を使用するには、Active Directory で gMSA オブジェクトを作成し、GKE で一致する gMSA リソースを作成して、新しく作成された Pod が gMSA 認証情報を取得できるようにする必要があります。

  1. Cloud Shell で、gMSA Webhook スクリプトをダウンロードして実行します。

    export K8S_GMSA_DEPLOY_DOWNLOAD_REV=8aba3cc755ecf5327c799af395286f2f03371aa0
    curl https://raw.githubusercontent.com/kubernetes-sigs/windows-gmsa/$K8S_GMSA_DEPLOY_DOWNLOAD_REV/admission-webhook/deploy/deploy-gmsa-webhook.sh -o deploy-gmsa-webhook.sh && chmod +x deploy-gmsa-webhook.sh
    
    ./deploy-gmsa-webhook.sh --file ./gmsa-webhook.yml --overwrite
    rm -drf gmsa-webhook-certs
    

    このスクリプトは、gMSA のカスタム リソース定義(CRD)マニフェストを GKE クラスタに追加し、gMSA 仕様を Pod に対して指定する Webhook をデプロイします。これで、gMSA 仕様をクラスタに格納し、Pod とコンテナの gMSA を構成できるようになりました。

    Kubernetes と gMSA の詳細については、Windows Pod とコンテナの GMSA を構成するをご覧ください。

GKE クラスタで gMSA を使う必要がある Windows アプリケーションを実行できるようになりました。たとえば、Windows Server ノードで ASP.NET ウェブ アプリケーションを実行できます。Windows 認証でユーザーをログインさせるようにアプリケーションを構成できます。また、アプリケーションが Pod の gMSA を使用して、リモート ネットワーク共有や SQL Server データベースにアクセスするように構成することも可能でます。

Active Directory との統合

次に、Active Directory 内に ASP.NET ウェブ アプリケーション用の gMSA を作成し、使用方法と使用可能なユーザーを構成した後、その構成を GKE に追加します。

ログインして PowerShell を起動する

  1. gmsa-dev-vm VM に接続します
  2. gMSA の作成が許可された Active Directory アカウントを使用して、Windows にログインします。

    そのアカウントは、Domain Admins グループのメンバーであるか、msDS-GroupManagedServiceAccount オブジェクトを作成できる必要があります。詳細については、グループの管理されたサービス アカウントのプロビジョニングをご覧ください。

    マネージド Microsoft AD を使用する場合、アカウントは Cloud Service Managed Service Account Administrators グループのメンバーである必要があります。詳細については、グループ マネージド サービス アカウントの作成をご覧ください。

  3. PowerShell を起動します。

    PowerShell
    

KDS ルートキーを作成する

gMSA を作成する前に、Active Directory ドメイン コントローラにキー配布サービス(KDS)のルートキーがあることを確認する必要があります。Active Directory は、KDS のルートキーを使用して gMSA のパスワードを生成します。

マネージド Microsoft AD を使用する場合は、次の手順をスキップできます。これは、ドメインの作成時にマネージド Microsoft AD が KDS ルートキーを作成するためです。

  1. gmsa-dev-vm で、Active Directory に KDS ルートキーがあるかどうかを確認します。

    Get-KdsRootKey
    

    鍵 ID がある場合は、このコマンドにより、それが表示されます。

  2. レスポンスで鍵 ID が返されない場合は、鍵を作成します。

    Add-KdsRootKey -EffectiveTime ((get-date).addhours(-10))
    

gMSA を作成する

gMSA を作成するときは、gMSA にアクセスできるパソコンの名前を指定する必要があります。セキュリティのベスト プラクティスとして、権限は、アプリケーションが実行されているインスタンスにのみ付与してください。ドメインに参加した Windows Server ノードプールを作成すると、ノードプールのコンピュータに新しい Active Directory グループが作成されます。グループの名前は、GKE がノードプール用に作成するマネージド インスタンス グループ(MIG)の名前と一致します。

  1. PowerShell で、Google Cloud プロジェクト ID、クラスタ名、Windows ノードプール名、gMSA 名、AD ドメイン名を、各変数に設定します。

    $ProjectId = "PROJECT-ID"
    $GkeClusterName = "cluster-1"
    $PermittedNodePool = "windows-server-pool"
    $GmsaName = "WebApp-01"
    $AdDomain = (Get-ADDomain).DNSRoot
    

    PROJECT-ID は、Google Cloud プロジェクト ID に置き換えます。

  2. kubectl ツールのクラスタ構成を設定します。

    gcloud config set project $ProjectId
    gcloud config set compute/zone "ZONE-NAME"
    

    ZONE-NAME は、GKE クラスタをデプロイしたゾーンに置き換えます。

  3. ノードプール用に作成された Active Directory グループのドメイン名を取得します。

    $IntanceGroupUri = gcloud container node-pools describe $PermittedNodePool `
        --cluster $GkeClusterName `
        --format="value(instanceGroupUrls)"
    $InstanceGroupName=([System.Uri]$intanceGroupUri).Segments[-1]
    $GroupDN=(Get-ADGroup -Filter "name -eq '$InstanceGroupName'")
    
    Write-Host $GroupDN.DistinguishedName
    
  4. gMSA を作成します。

    New-ADServiceAccount -Name $GmsaName `
    -DNSHostName "$GmsaName.$AdDomain" `
    -PrincipalsAllowedToRetrieveManagedPassword $GroupDN
    
  5. gMSA が作成されたことを確認します。

    Get-ADServiceAccount -Identity $GmsaName
    

    gMSA が作成された場合、出力は次のようになります。

    DistinguishedName : CN=WebApp01,CN=Managed Service Accounts,DC=corp,DC=example,DC=com
    Enabled           : True
    Name              : WebApp01
    ObjectClass       : msDS-GroupManagedServiceAccount
    ObjectGUID        : 5afcff45-cf15-467d-aaeb-d65e53288253
    SamAccountName    : WebApp01$
    SID               : S-1-5-21-780151012-601164977-3226406772-2103
    UserPrincipalName :
    

gMSA を GKE に追加する

Kubernetes クラスタで gMSA を使用するには、Kubernetes に gMSA リソースを作成し、その使用を許可する名前空間とアカウントを構成する必要があります。

  1. gmsa-dev-vm の PowerShell で、git ツールをインストールします。

    Install-Script -Name Install-Git -Force
    Install-Git.ps1
    $env:Path += ";c:\program files\git\bin"
    
  2. kubectl ツールをインストールします。

    $version = (Invoke-WebRequest -UseBasicParsing -Uri "https://dl.k8s.io/release/stable.txt").Content
    $uri = "https://dl.k8s.io/release/$version/bin/windows/amd64/kubectl.exe"
    New-Item -Type Directory $env:ProgramFiles\kubectl
    Start-BitsTransfer -Source $uri -Destination $env:ProgramFiles\kubectl\
    $env:Path += ";$env:ProgramFiles\kubectl"
    
  3. GKE クラスタの認証情報で kubectl ツールを初期化します。

    gcloud container clusters get-credentials $GkeClusterName
    
  4. gMSA 認証情報仕様ファイルを作成します。

    Install-Module CredentialSpec -Force
    $GmsaName = $GmsaName.ToLower()
    $CredSpecFile = Join-Path $env:TEMP "$GmsaName-credspec.json"
    New-CredentialSpec -AccountName $GmsaName -Path $CredSpecFile
    
    $CredentialsSpec=@{
    "apiVersion" = "windows.k8s.io/v1alpha1";
    "kind" = "GMSACredentialSpec";
    "metadata" = @{"name" = $GmsaName}
    "credspec" = (Get-Content $CredSpecFile | ConvertFrom-Json)
    }
    
    $CredentialsSpec | ConvertTo-Json -Depth 5 | Set-Content $CredSpecFile
    

    Kubernetes の GMSACredentialSpec リソースの名前には、小文字を使用する必要があります

    このスクリプトでは、この制限を遵守するため、$GmsaName 変数の大文字を小文字に変換します。

    このスクリプトでは、マネージド サービス アカウントのテストが失敗したことを示す警告メッセージが表示されます(想定済の動作)。開発用 VM は、gMSA に割り当てられたグループのメンバーではないため、VM から gMSA をテストすることはできません。警告メッセージが表示されても、gMSA 認証情報仕様を生成するコマンドが停止されることはありません。

  5. gMSA 認証情報仕様を GKE クラスタに追加します。

    kubectl apply -f $CredSpecFile
    
  6. GitHub リポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/gke-aspnet-gmsa.git
    cd gke-aspnet-gmsa
    
  7. gMSA RBAC オブジェクトをクラスタに追加します。

    kubectl apply -f gmsa-rbac-webapp-01.yaml
    

ウェブ アプリケーションのデプロイと使用

次に、ウェブ アプリケーションとコンテナ イメージをビルドし、新しいコンテナ イメージを GKE クラスタにデプロイします。さらに、ブラウザでウェブ アプリケーションを開き、それが gMSA を使用できることを確認します。

ASP.NET ウェブ アプリケーションをビルドしてデプロイする

  1. gmsa-dev-vm の PowerShell で、レジストリのロケーション、レジストリ名、イメージタグを、各変数に設定します。

    $RegistryLocation = "STORAGE-REGION.gcr.io"
    $ProjectsRegistry = "$RegistryLocation/$ProjectId"
    $ImageTag = "$ProjectsRegistry/test-gmsa:latest"
    

    STORAGE-REGION は、コンテナ イメージを保存するロケーションに置き換えます。サポートされている値は、useuasia です。開発用 VM と GKE クラスタを作成するリージョンに近いロケーションを選択します。

  2. コンテナ イメージをビルドします。

    docker build -t $ImageTag -f Dockerfile-WINDOWS_LTSC .
    
  3. コンテナ イメージを Container Registry に push します。

    gcloud auth configure-docker $RegistryLocation --quiet
    docker push $ImageTag
    
  4. アプリケーションの YAML ファイルをダウンロードして、gMSA 構成で更新します。

    $ApplicationYaml = Join-Path $env:TEMP "gmsa-test-webapp-01.yaml"
    
    (Get-Content gmsa-test-webapp-01.yaml.template) `
    -Replace '\${registry_path}',$ProjectsRegistry | `
    Set-Content $ApplicationYaml
    
  5. GKE クラスタに、ウェブ アプリケーションをデプロイします。

    kubectl apply -f $ApplicationYaml
    

ASP.NET ウェブ アプリケーションが実行されていることを確認する

ウェブ アプリケーションは、LoadBalancer Service を使用してインターネットに公開されます。ウェブ アプリケーションを閲覧する前に、まずは Pod と Service がデプロイされるのを待つ必要があります。Windows Server Core コンテナ イメージはサイズが大きいため(ウェブ アプリケーション イメージが 7 GB 以上)、Pod のデプロイには数分かかることがあります。また、ノードがイメージをダウンロードしてコンテナを作成することにも、しばらく時間がかかります。

  1. Pod のステータスを確認します。

    kubectl get pods --selector=app=gmsa-test-webapp-01
    

    出力で Pod のステータスが Running として表示されるまでこのコマンドを繰り返します。

    NAME                                   READY     STATUS    RESTARTS   AGE
    gmsa-test-webapp-01-76c6d64975-zrtgq   1/1       Running   0          28s
    

    Pod のステータスが Pending のまま、ContainerCreating または Running のいずれにも変わらない場合は、Windows ノードのソースイメージを調べて、Windows Server 2019 であることを確認してください。また、GKE バージョンと Windows Server バージョンがどのようにマッピングされるかについては、バージョン マッピングの表もご覧ください。バージョンが一致しない場合は、ノードの Windows Server バージョンと一致するベースコンテナ イメージDockerfile-WINDOWS_LTSC ファイルを更新し、ASP.NET ウェブ アプリケーションをビルドしてデプロイするの手順を繰り返します。

  2. Service のステータスを確認します。

    kubectl get service --selector=app=gmsa-test-webapp-01
    

    Service に外部 IP アドレスが割り当てられていることが出力に表示されるまで、このコマンドを繰り返します。

    NAME                   TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)        AGE
    gmsa-test-webapp-01    LoadBalancer   10.44.2.112   external-ip    80:32233/TCP   17s
    
  3. 出力の EXTERNAL-IP の値をメモします。この値は後で必要になります。

ASP.NET ウェブ アプリケーションで予備テストを実行する

Pod が実行され、ネットワーク ロードバランサを介してインターネットからアクセスできるようになりました。次に、予備テストを実行して、コンテナが正常にデプロイされ、gMSA を使用する権限が付与されていることを確認します。

  1. ブラウザで、http://EXTERNAL-IP にアクセスして、gMSA テスト用ウェブ アプリケーションを表示します。

    EXTERNAL-IP は、前の手順で取得した IP アドレスに置き換えます。

  2. [Preflight Checks] セクションまでスクロールし、[Run Preflight Checks] ボタンをクリックして、すべてのテストに合格したことを確認します。

    テストに合格すると、出力は次のようになります。

    [PASS]  Active Directory RSAT PowerShell Module Installed
    
    [PASS]  IIS Document Root found
            C:\inetpub\wwwroot\
    
    [PASS]  PowerShell Scripts Folder found
            C:\inetpub\wwwroot\Powershell\
    
    [PASS]  Container Diagnostic Script found
            C:\inetpub\wwwroot\Powershell\\containerDiag.ps1
    
    [PASS]  Domain Diagnostic Script found
            C:\inetpub\wwwroot\Powershell\\domainDiag.ps1
    
    [RES]   Result: PASS   All checks passed! Please proceed to run the different tests.
    
  3. [Container Information] セクションまでスクロールし、[Run Script] ボタンをクリックします。コンテナとノードに関する情報が表示され、エラーが表示されていないことを確認します。

Windows コンテナで gMSA を使用する

ウェブ アプリケーションでいくつかのテストを実行して、gMSA 設定が正しく機能していることを確認できるようになりました。それぞれのテストでは、gMSA を異なる目的で使用します。すべてのテストが成功した場合は、gMSA が適切に構成されています。

gMSA コンテナの構成を検証する

  • [Domain Connectivity] セクションまでスクロールして、[Account Name] ボックスに gMSA の名前(WebApp-01)を入力し、[Run Script] をクリックします。テストが完了するまで数秒待ちます。

    出力は次のようになります。

    *****   C O N T A I N E R   D I A G N O S T I C S   *****
    
    [INFO]  Starting script execution at 01-05-2021-13:53:11
    
    [INFO]  Using gMSA: WebApp-01
    
    [PASS]  gMSA Account found in Active Directory
            CN=WebApp01,CN=Managed Service Accounts,DC=corp,DC=example,DC=com
    
    [PASS]  This Container (gmsa-test-webapp01-5bc485b8d5-9lbb7) is running on a GKE Windows Node that is authorized to use WebApp01
    
    [INFO]  Script execution complete at 01-05-2021-13:53:12
    
    *****      E N D   O F   D I A G N O S T I C S      *****
    

    このスクリプトでは、2 つの PowerShell コマンドレットを使用して gMSA へのアクセスをテストします。

    • Get-ADServiceAccount: このコマンドレットは、gMSA に関する情報を取得します。コマンドレットが正常に実行された場合は、コンテナが有効な gMSA で実行されています。
    • Test-ADServiceAccount: このコマンドレットは、gMSA 認証情報を取得できるかどうかをテストします。コマンドレットが正常に実行された場合、コンテナは gMSA 認証情報へのアクセスが許可されている Windows Server ノードで実行されています。

Windows 認証でユーザー ログインを行う

  1. ページ上部のナビゲーション バーで [Login] をクリックします。
  2. 認証情報の入力を求めるプロンプトが表示されたら、ドメインのユーザー名とパスワードを入力します。
  3. [Secure] ページにアカウント情報が表示され、認証情報を要求するプロンプトが表示されていない場合は、ブラウザが現在の ID を使用して自動的にログインしています。

    認証されると、[Secure] ページが表示されます。次の 3 つのセクションが表示されていることを確認します。

    • User information: ユーザー名と使用された認証の種類が表示されます。
    • Groups: 所属するグループのリストが表示されます。リスト内のグループ名は、Active Directory から取得されます。
    • User Claims: ログイン時に Active Directory によって提供されるユーザーのクレームのリストを表示します。グループ メンバーのクレームには、名前ではなく Active Directory グループの SID が表示されます。

ASP.NET ウェブ アプリケーションでは、統合 Windows 認証のサポートに加え、リモート サーバーを呼び出すときに gMSA を使用して認証を行えます。gMSA を使用すると、ウェブ アプリケーションなど Windows コンテナで実行されているアプリケーションが、SQL Server インスタンスや SMB ベースのネットワーク共有などの Windows 認証を必要とするネットワーク内のリソースにアクセスできます。

トラブルシューティング

セットアップ プロセスの途中、またはウェブ アプリケーションのテスト中にエラー メッセージが表示された場合は、次のトラブルシューティング ページをご覧ください。

本番環境アプリケーションに関するその他の考慮事項

ここで行った手順は、チュートリアルに最適な道筋を提供する目的で作成されています。以降のセクションで説明するように、本番環境では、手順の一部を変更することで、結果をよりしっかりしたものにできます。

Windows Server ノードプールに関する考慮事項

gMSA を使用する独自のアプリケーションをデプロイする予定があり、アプリケーションがクライアント セッションをサポートする場合、ノードプールには、ノードを 2 つ以上作成することをおすすめします。複数のノードがあると、プロセス外のセッション ストレージを使用して、アプリケーションが分散セッションを適切に処理できるかどうかを確認できます。

このチュートリアルでは、アプリケーションをホストする Windows Server ノードプールを 1 つ作成します。ただし、クラスタに複数の Windows Server ノードプールを作成する必要が生じることがあります。たとえば、一方は HDD 永続ディスク(PD)を使用するノードプールとして、もう一方は SSD PD を使用するノードプールとする場合です。アプリケーションを複数のノードプールにデプロイする必要がある場合は、New-ADServiceAccount コマンドレットを使用して gMSA を作成する際に、Active Directory のグループ オブジェクトの配列を PrincipalsAllowedToRetrieveManagedPassword パラメータに対して指定します。

gMSA とサービスのプリンシパル名(SPN)に関する考慮事項

アプリケーションで、Kerberos を使用してユーザーを認証する必要がある場合(ID 委任をサポートする場合など)は、カスタム DNS を使用してアプリケーションにアクセスし、サービス プリンシパル名(SPN)で gMSA を構成する必要があります。たとえば、ロードバランサが https://my-web-app/ を介して GKE でアプリケーションを公開する場合は、次のいずれかの方法で HTTP/my-web-app という名前の SPN を作成する必要があります。

  • 新しい gMSA の場合は、必要な SPN を使用して gMSA を作成します。次に例を示します。

    New-ADServiceAccount -Name $GmsaName `
    -DNSHostName "$GmsaName.$AdDomain" `
    -PrincipalsAllowedToRetrieveManagedPassword $Groups `
    -ServicePrincipalNames "HTTP/my-web-app", "HTTP/my-web-app.$AdDomain"
    
  • 既存の gMSA の場合は、Set-ADServiceAccount を呼び出して、必要な SPN を gMSA に追加します。次に例を示します。

    Set-ADServiceAccount $GmsaName -ServicePrincipalNames @{Add="HTTP/my-web-app", "HTTP/my-web-app.$AdDomain"}
    

DNS 構成によっては、HTTP/www.my-web-appHTTP/www.my-web-app.$AdDomain の SPN の作成も必要になる場合があります。

TCP バインディングと Windows 認証で構成された WCF サービスなど、HTTP 以外のプロトコルの場合は、HOST/ SPN など、他のタイプの SPN の作成が必要になる場合があります。

IIS アプリケーション プールの ID の選択

ASP.NET Web アプリケーションは、IIS ウェブサーバー上の Windows で実行されます。IIS では、同じプロセスを共有するウェブ アプリケーションのグループを構成します。このグループは、アプリケーション プールと呼ばれます。各アプリケーション プールは、w3wp という名前の専用プロセスでホストされます。IIS アプリケーション プールは、プロセスが 32 ビットか 64 ビットかなどのプロセス構成を指定し、プロセスの ID を指定します。Windows コンテナでウェブ アプリケーションを実行する場合は、組み込みのネットワーク サービス アカウントを使用するようにアプリケーション プールのプロセス ID を設定します。

IIS もサポートしているローカルのアプリケーション プールの ID アカウントは、Windows コンテナには必要ありません。アプリケーション プールの ID アカウントは、同じ IIS インスタンスで複数のウェブ アプリケーションを実行するときに、ローカル セキュリティ境界を適用する手段として IIS によって作成されました。Windows コンテナでは、各ウェブ アプリケーションが個別のコンテナでホストされ、コンテナ自体にセキュリティ境界があるため、コンテナ内にセキュリティ境界を作成する必要はありません。

アプリケーション プールの ID は、ネットワーク サービス アカウントを使用するように構成されていますが、認証が必要な外部リソースにアプリケーションがリクエストを行うと、アプリケーションは Windows コンテナ用に構成された gMSA を使用して認証を行います。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

個々のリソースを削除する

Google Cloud プロジェクトを残し、このチュートリアルで作成した Google Cloud リソースを削除しない場合は、リソースを個別に削除できます。

Active Directory の変更を元に戻す

  1. 開発用 VM に接続し、Active Directory ドメインに対する管理者権限を付与されているユーザーとしてログインします。
  2. gmsa-dev-vm VM で PowerShell がまだ起動されていない場合は、起動します。

    PowerShell
    
  3. gMSA を削除します。

    Remove-ADServiceAccount -Identity "WebApp-01" -Confirm:$false
    

クラウド リソースを削除する

  1. Cloud Console で、Cloud Shell をアクティブにします。

    Cloud Shell をアクティブにする

  2. gcloud 環境を初期化します。

    gcloud config set project PROJECT-ID
    gcloud config set compute/zone ZONE-NAME
    

    PROJECT-ID は、実際の Google Cloud プロジェクト ID に置き換え、ZONE-NAME は、GKE クラスタと開発用 VM をデプロイしたゾーンに置き換えます。

  3. 開発用 VM を削除します。

    gcloud compute instances delete gmsa-dev-vm --quiet
    
  4. サービス アカウントを削除します。

    gcloud iam service-accounts delete dev-vm@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com --quiet
    
  5. GKE クラスタを削除します。

    gcloud container clusters delete cluster-1 --quiet
    
  6. Active Directory コントローラのファイアウォール ルールを作成した場合は、そのルールを削除します。

    gcloud compute firewall-rules delete allow-gke-pods-to-ad --quiet
    
  7. ウェブ アプリケーション イメージを削除します。

    gcloud container images delete STORAGE-REGION.gcr.io/$GOOGLE_CLOUD_PROJECT/test-gmsa --force-delete-tags --quiet
    

    STORAGE-REGION は、コンテナ イメージを保存するために選択したロケーションに置き換えます。サポートされている値は、useuasia です。

終了するには、VM が自動的にドメインに参加するように Active Directory を構成するのクリーンアップ手順を行います。

次のステップ