在 GKE Windows 容器中部署使用 Windows 驗證的 ASP.NET 應用程式


本教學課程說明如何建立使用 IIS 和整合式 Windows 驗證的 ASP.NET 網頁應用程式,以及如何使用 Windows 容器將該應用程式部署至已加入網域的 Windows Server 節點 Google Kubernetes Engine (GKE) 叢集。這項設定有助於在 Windows 容器中部署 ASP.NET 應用程式,以便應用程式向其他 Windows 資源進行驗證。 Google Cloud本教學課程也會說明如何在 Active Directory 中建立群組管理服務帳戶 (gMSA),以及如何在 GKE 中設定網頁應用程式部署作業,以便使用該帳戶。

本教學課程適用對象為系統管理員。本文假設您熟悉 Active Directory,且有使用 Google Kubernetes Engine (GKE) 的經驗。

目標

  • 建立 GKE 叢集,其中包含已加入網域的 Windows Server 節點,並將叢集設定為支援 Active Directory gMSA。
  • 建構及部署 ASP.NET 網頁應用程式容器映像檔,該映像檔使用 IIS 和整合式 Windows 驗證。

費用

在本文件中,您會使用 Google Cloud的下列計費元件:

如要根據預測用量估算費用,請使用 Pricing Calculator

初次使用 Google Cloud 的使用者可能符合免費試用資格。

事前準備

  1. 請按照「設定 Active Directory,讓 VM 自動加入網域」教學課程中的步驟,建立 Active Directory 網域加入 Cloud Run 服務。

  2. 如果您是在與建立 VM 的專案不同的專案中執行本教學課程,請在 Google Cloud 專案中執行啟用專案以自動加入網域的步驟。 Google Cloud

    完成其他教學課程後,您會獲得新的 Cloud Run 服務,且其網址會顯示在 PowerShell 視窗中 ($RegisterUrl 變數的值)。記下服務的位址,因為本教學課程會用到。

  3. 請確認您已啟用 Compute Engine、GKE、Cloud Build、Artifact Registry 和 Cloud Resource Manager API:

    啟用 API

    完成本教學課程後,您可以刪除自己建立的資源,避免繼續計費。詳情請參閱清除所用資源一節。

架構

在已加入網域的 Windows Server 中執行的 Windows 應用程式,通常會使用 Microsoft Active Directory (AD) 身分驗證使用者和應用程式。常見用途如下:

  • 建立 ASP.NET 網路應用程式,使用整合式 Windows 驗證,在 Active Directory 使用者嘗試登入網路應用程式時驗證身分。
  • 建立應用程式,使用伺服器的 Active Directory 電腦帳戶透過網路存取資源,例如遠端 SMB 共用或遠端 Microsoft SQL Server 執行個體。

Windows 容器無法加入網域,因此在 Active Directory 中沒有電腦帳戶。因此,在 Windows 容器上執行的 ASP.NET 網頁應用程式無法透過整合式 Windows 驗證功能驗證 Active Directory 使用者,也無法存取網路中的安全資源。如要進一步瞭解 ASP.NET 如何存取受保護的資源,請參閱 Microsoft 說明文件中的「應用程式集區身分」。

Windows 容器可以使用 Active Directory 群組受管理服務帳戶 (gMSA) 身分,存取 Active Directory 和網路中的其他安全資源,例如檔案共用和 SQL Server 執行個體,而不必使用電腦帳戶。詳情請參閱 Microsoft 說明文件中的「群組管理服務帳戶總覽」。

下方架構圖顯示本教學課程使用的資源:

GKE 上已加入 Active Directory 網域的 Windows Server 容器。

下圖顯示下列元素:

  • 開發 VM。在本教學課程中,您會建立 Windows Server VM,用於建構 ASP.NET 網頁應用程式容器映像檔,以及建立 gMSA。
  • GKE 叢集和節點。本教學課程中的 GKE 叢集同時具有 Linux 節點集區和 Windows Server 節點集區,用途如下:
    • Linux 節點會執行僅在 Linux 作業系統上執行的系統元件,例如 GKE 指標伺服器。
    • Windows Server 節點用於代管 Windows Server 容器,並加入 Active Directory 網域。
  • Active Directory 基礎架構。如要讓 GKE Windows 節點加入網域,請先完成設定虛擬機的 Active Directory,讓虛擬機自動加入網域教學課程。在該教學課程中,您會建立 Cloud Run 服務,負責在 Active Directory 中註冊新電腦 (執行個體),並為每個新執行個體提供臨時密碼,供執行個體完成網域加入程序。Windows Server 節點集區中的每個新執行個體都會呼叫 Cloud Run 服務,將自己加入 Active Directory 網域。
  • 網路負載平衡器。當內部部署使用者開啟瀏覽器並瀏覽 ASP.NET 網頁應用程式時,流量會通過網路負載平衡器。為網路應用程式建立 GKE LoadBalancer 服務時,GKE 會建立負載平衡器。使用者也會將 Active Directory 憑證傳遞至網頁應用程式,藉此向網頁應用程式進行驗證。

建立基礎架構

完成相關教學課程後,請為本教學課程建立基礎架構元件,包括:

  • 搭載 ASP.NET 網頁應用程式容器映像檔的 Windows Server VM。
  • 具有 Windows Server 節點集區的 GKE 叢集。
  • 防火牆規則,可讓 GKE Pod 存取 Active Directory。
  • GKE 叢集中的 Webhook,可處理部署作業中的 gMSA 資源設定和填入作業。

建立開發 VM

您建立的 Windows Server 容器映像檔,必須與建構容器映像檔的 VM 所用 Windows Server 版本相符。這個版本也必須與 GKE Windows Server 節點的 Windows Server 版本相符。在不同版本的 Windows Server 中建立容器映像檔或執行容器,都會導致錯誤。如要進一步瞭解 Windows 容器的相容性需求,請參閱將容器主機版本與容器映像檔版本相符

在本教學課程中,VM、GKE 中的 Windows Server 節點和容器映像檔,都會使用 Windows Server 的長期維護通道 (LTSC) 2022 版本。詳情請參閱「Windows Server 版本與 GKE 版本之間的對應關係」。

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 如果 PowerShell 已開啟,請輸入 exit 關閉。
  3. 為網路和子網路名稱,以及 Active Directory 服務網址設定環境變數:

    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 服務網址。
  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. 將服務帳戶的存取權授予 Artifact Registry:

    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
        --role="roles/artifactregistry.writer"
    
  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 資源,才能控管哪些 Pod 可使用 gMSA。

  8. 建立新的 Windows Server 2022 VM:

    gcloud compute instances create gmsa-dev-vm \
        --image-project windows-cloud \
        --image-family windows-2022-core \
        --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"
    

    如果您打算將容器化應用程式部署至 Windows Server 2019 容器,請將 --image-family 參數值變更為 windows-2019-core-for-containers

    https://www.googleapis.com/auth/cloud-platform 範圍可讓執行個體存取所有 Google Cloud API,具體取決於為執行個體服務帳戶定義的 IAM 角色。

    系統會為 VM 指派外部 IP 位址,讓 VM 能與網際網路通訊。VM 必須具備網際網路存取權,才能下載 gitkubectl 等多種公用程式,以及從 GitHub 下載 ASP.NET 網頁應用程式。

    sysprep 階段,新執行個體會加入 Active Directory 網域,讓您使用網域帳戶遠端存取執行個體。sysprep 指令中的指令碼也會安裝 Active Directory 的 PowerShell 模組。

建立 Artifact Registry Docker 存放區

  1. 在 Cloud Shell 中,為新的 Artifact Registry 存放區設定預設位置:

    gcloud config set artifacts/location LOCATION
    

    LOCATION 替換為要建立 Artifact Registry 存放區的區域。為減少延遲,建議您選取部署開發 VM 的相同區域。

  2. 建立 Artifact Registry Docker 存放區:

    gcloud artifacts repositories create windows-container-images \
        --repository-format=docker
    

建立 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,即可部署最新 Kubernetes 版本的 GKE 叢集。--enable-ip-alias 參數會開啟別名 IP。Windows Server 節點必須使用別名 IP。

在 GKE 中建立 Windows Server 節點集區

透過 CLI 建立新的 GKE 叢集時,系統會建立含有 Linux 節點集區的叢集。如要在 GKE 上使用 Windows Server,請建立 Windows Server 節點集區。

GKE 叢集必須至少有一個 Linux 節點,才能執行叢集的內部 (系統) 容器。您無法只使用 Windows Server 節點建立 GKE 叢集。

  1. 在 Cloud Shell 中,為 Windows 伺服器節點集區的名稱設定環境變數:

    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_CONTAINERD \
        --windows-os-version=ltsc2022 \
        --num-nodes 2 \
        --no-enable-autoupgrade \
        --metadata sysprep-specialize-script-ps1="iex((New-Object System.Net.WebClient).DownloadString('$AD_JOIN_SERVICE_URL'))"
    

    如果您打算將容器化應用程式部署至 Windows Server 2019 容器,請將 --windows-os-version 參數變更為 ltsc2019

    sysprep-specialize-script-ps1 中繼資料鍵是內建鍵, 指向在 GCESysprep 步驟中執行的 PowerShell 指令碼,也就是執行個體首次啟動前執行的指令碼。

    iex Cmdlet 會從您部署至 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 Services (TCP/9389)

您可以根據指派給網域控制器的服務帳戶套用規則,也可以使用網路標記套用規則,如本教學課程所示。如要進一步瞭解 Active Directory 相關通訊埠,請參閱「Active Directory port and protocol requirements」(Active Directory 通訊埠和通訊協定需求) 和「using Active Directory across firewalls」(在防火牆之間使用 Active Directory) 的文件。

如果您使用Managed Service for Microsoft Active Directory (Managed Microsoft AD),可以略過這個程序。

  1. 在 Cloud Shell 中,取得 GKE 叢集的 Pod IP 位址範圍:

    CLUSTER_IP_RANGE=`gcloud container clusters describe $GKE_CLUSTER_NAME --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 的網路標記。

設定 GKE,支援使用 gMSA

如要在 Windows Server 節點中使用 gMSA,您需要在 Active Directory 中建立 gMSA 物件、在 GKE 中建立相符的 gMSA 資源,並允許新建立的 Pod 擷取 gMSA 憑證。

  1. 在 Cloud Shell 中,下載並執行 gMSA Webhook 指令碼:

    export K8S_GMSA_DEPLOY_DOWNLOAD_REV=b685a27adc40511bb5756dfb3ada2e8578ee72e1
    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 --namespace gmsa-webhook --overwrite
    rm -drf gmsa-webhook-certs
    

    指令碼會將 gMSA自訂資源定義 (CRD) 資訊清單新增至 GKE 叢集,並部署 Webhook,將 gMSA 規格提供給 Pod。您現在可以在叢集中儲存 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. 輸入 15 即可退出選單,返回指令列 (PowerShell)。

安裝容器執行階段

Windows Server 2022 需要容器執行階段 (例如 Docker Community Edition (CE)),才能建立及執行 Windows 容器。如要進一步瞭解如何在 Windows Server 上安裝容器執行階段,請參閱 Microsoft 說明文件中的「開始使用:準備 Windows 容器」。

如果您使用 windows-2019-core-for-containers 映像檔建立開發 VM,可以略過下列程序,因為該映像檔已安裝 Docker。

  1. 安裝 Docker Community Edition (CE):

    Invoke-WebRequest -UseBasicParsing -o install-docker-ce.ps1 `
       "https://raw.githubusercontent.com/microsoft/Windows-Containers/Main/helpful_tools/Install-DockerCE/install-docker-ce.ps1"
    .\install-docker-ce.ps1
    

    如果在安裝過程中遠端桌面連線關閉,請重新連線至 VM。

  2. 等待安裝程序完成,然後輸入 exit 關閉新的 PowerShell 視窗。

  3. 輸入 15 即可退出選單,返回指令列 (PowerShell)。

建立 KDS 根金鑰

建立 gMSA 前,請務必確認 Active Directory 網域控制站具有金鑰發布服務 (KDS) 根金鑰。Active Directory 會使用 KDS 根金鑰產生 gMSA 的密碼。

如果您使用 Managed Microsoft AD,可以略過下列程序,因為建立網域時,Managed Microsoft AD 會建立 KDS 根金鑰。

  1. gmsa-dev-vm 上,檢查 Active Directory 是否已有 KDS 根金鑰:

    Get-KdsRootKey
    

    如果金鑰 ID 存在,這項指令會顯示該 ID。

  2. 如果沒有在回覆中取得金鑰 ID,請建立金鑰:

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

建立 gMSA

建立 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. 設定 gcloud 工具的叢集設定:

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

    ZONE-NAME 替換為您部署 GKE 叢集的區域。

  3. 擷取為節點集區建立的 Active Directory 群組網域名稱:

    $InstanceGroupUri = gcloud container node-pools describe $PermittedNodePool `
        --cluster $GkeClusterName `
        --format="value(instanceGroupUrls)"
    $InstanceGroupName=([System.Uri]$instanceGroupUri).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-gcloud-auth-plugin 二進位檔:

    gcloud components install gke-gcloud-auth-plugin
    

    等待幾分鐘,讓安裝程序完成。

  4. 使用 GKE 叢集的憑證初始化 kubectl 工具:

    gcloud container clusters get-credentials $GkeClusterName
    
  5. 建立 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/v1";
    "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 憑證規格。

  6. 將 gMSA 憑證規格新增至 GKE 叢集:

    kubectl apply -f $CredSpecFile
    
  7. 複製 GitHub 存放區:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/windows/aspnet-gmsa/
    
  8. 將 gMSA RBAC 物件新增至叢集:

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

    gmsa-rbac-webapp-01.yaml 會為 gMSA 建立 ClusterRole RBAC 物件,然後將新的叢集角色繫結至 default 命名空間中的預設服務帳戶。如要將應用程式部署至其他命名空間,請編輯 gmsa-rbac-webapp-01.yaml 檔案,並變更角色繫結和服務帳戶的命名空間。

部署及使用網頁應用程式

接著,您會建構網頁應用程式和容器映像檔,將新的容器映像檔部署到 GKE 叢集,並在瀏覽器中開啟網頁應用程式,確認網頁應用程式可以使用 gMSA。

建構及部署 ASP.NET 網頁應用程式

  1. gmsa-dev-vm 的 PowerShell 中,設定登錄位置、登錄名稱和映像檔標記的變數:

    $RegistryLocation = "LOCATION-docker.pkg.dev"
    $ProjectsRegistry = "$RegistryLocation/$ProjectId"
    $ImageTag = "$ProjectsRegistry/windows-container-images/test-gmsa:latest"
    

    LOCATION 替換為您建立 Artifact Registry 存放區的位置。

  2. 建構容器映像檔:

    docker build -t $ImageTag -f Dockerfile-WINDOWS_LTSC2022 .
    

    如要為 Windows Server 2019 建構容器映像檔,請將 -f 參數值設為 Dockerfile-WINDOWS_LTSC2019

  3. 將容器映像檔推送至 Artifact Registry:

    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 '\${image_path}',$ImageTag | `
    Set-Content $ApplicationYaml
    

    如果您在 GKE 中建立 Windows Server 2019 節點,請編輯應用程式的 YAML 檔案,並將 cloud.google.com/gke-windows-os-version 的值從 2022 變更為 2019

  5. 將網頁應用程式部署至 GKE 叢集:

    kubectl apply -f $ApplicationYaml
    

確認 ASP.NET 網頁應用程式正在執行

網頁應用程式會透過 LoadBalancer 服務公開至網際網路。您必須等待 Pod 和服務部署完成,才能瀏覽網路應用程式。部署 Pod 可能需要幾分鐘,因為 Windows Server Core 容器映像檔很大 (網頁應用程式映像檔超過 7 GB),節點需要一些時間才能下載映像檔並建立容器。

  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 2022。您也可以查看版本對應表,瞭解 GKE 版本與 Windows Server 版本的對應關係。如果版本不符,請複製 Dockerfile-WINDOWS_LTSC2022 檔案,將新檔案中的基本容器映像檔設為與節點的 Windows Server 版本相符,然後重複上述步驟,建構及部署 ASP.NET 網頁應用程式

  2. 檢查服務狀態:

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

    重複執行指令,直到輸出內容顯示服務具有外部 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. 捲動至「預檢」部分,然後按一下「執行預檢」按鈕,確認所有測試都通過。

    如果測試通過,輸出內容如下:

    [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 容器設定

  • 捲動至「網域連線」部分,在「帳戶名稱」方塊中輸入 gMSA 的名稱 (WebApp-01),然後按一下「執行指令碼」。稍待片刻,等待測試完成。

    輸出結果會與下列內容相似:

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

    指令碼會使用兩個 PowerShell cmdlet 測試 gMSA 的存取權:

    • Get-ADServiceAccount:這個 Cmdlet 會擷取 gMSA 的相關資訊。如果這個 Cmdlet 順利執行,表示容器正在使用有效的 gMSA 執行。
    • Test-ADServiceAccount:這個 Cmdlet 會測試是否可以擷取 gMSA 憑證。如果 Cmdlet 順利執行,表示容器正在 Windows Server 節點中執行,且該節點有權存取 gMSA 憑證。

使用 Windows 驗證登入使用者

  1. 按一下頁面頂端導覽列的「登入」
  2. 當系統提示您輸入憑證時,請輸入網域使用者名稱和密碼。
  3. 如果看到「安全」頁面顯示帳戶資訊,且系統未提示您輸入憑證,表示瀏覽器已使用目前的身份自動登入。

    通過驗證後,您會看到「安全」頁面。確認畫面顯示下列三個部分:

    • 使用者資訊:顯示您的使用者名稱和使用的驗證類型。
    • 群組:顯示您所屬的群組清單。清單中的群組名稱是從 Active Directory 擷取而來。
    • 使用者聲明:顯示使用者在登入期間由 Active Directory 提供的聲明清單。群組成員資格聲明會顯示 Active Directory 群組 SID,而非名稱。

除了支援整合式 Windows 驗證外,ASP.NET 網路應用程式在呼叫遠端伺服器時,也可以使用其 gMSA 進行驗證。使用 gMSA,網路應用程式和 Windows 容器中執行的任何其他應用程式,都可以存取網路中需要 Windows 驗證的資源,例如 SQL Server 執行個體和 SMB 型網路共用。

疑難排解

如果在設定程序或測試網頁應用程式時遇到任何錯誤訊息,請參閱下列疑難排解頁面:

實際運作環境應用程式的其他注意事項

您遵循的指示是為了提供教學課程的最佳路徑。在正式環境中,您可能會變更部分程序,讓結果更可靠,詳情請參閱下列章節。

Windows Server 節點集區注意事項

如果您打算部署使用 gMSA 的自有應用程式,且該應用程式支援用戶端工作階段,建議您在節點集區中建立至少兩個節點。多個節點可讓您使用程序外工作階段儲存空間,驗證應用程式是否能正確處理分散式工作階段。

在本教學課程中,您將建立單一 Windows Server 節點集區,用於代管應用程式。不過,您可能需要在叢集中建立多個 Windows Server 節點集區,例如一個節點集區使用 HDD 永久磁碟 (PD),另一個節點集區使用 SSD PD。如要將應用程式部署到多個節點集區,請在使用 New-ADServiceAccount cmdlet 建立 gMSA 時,將 Active Directory 群組物件陣列提供給 PrincipalsAllowedToRetrieveManagedPassword 參數。

gMSA 和服務主體名稱 (SPN) 注意事項

如果應用程式需要使用 Kerberos 驗證使用者身分 (例如支援身分委派),您必須使用自訂 DNS 存取應用程式,並使用服務主體名稱 (SPN) 設定 gMSA。 舉例來說,如果負載平衡器透過 https://my-web-app/ 在 GKE 上公開應用程式,您需要透過下列其中一種方式建立名為 HTTP/my-web-app 的 SPN:

  • 如果是新的 gMSA,請建立 gMSA 並提供必要的 SPN。例如:

    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。

如果是使用非 HTTP 通訊協定 (例如設定 TCP 繫結和 Windows 驗證的 WCF 服務),您可能需要建立其他類型的 SPN,例如 HOST/ SPN。

選擇 IIS 應用程式集區身分

ASP.NET 網路應用程式會在 IIS 網路伺服器上的 Windows 中執行。在 IIS 中,您可以設定共用相同程序的網頁應用程式群組。這個群組稱為「應用程式集區」。每個應用程式集區都會在名為 w3wp 的專屬程序中代管。IIS 應用程式集區提供程序設定,例如程序是 32 位元或 64 位元程序,並提供程序的 ID。在 Windows 容器中執行網頁應用程式時,請將應用程式集區的程序身分設為使用內建的「網路服務」帳戶。

Windows 容器不需要 IIS 支援的本機應用程式集區身分帳戶。IIS 會建立應用程式集區身分帳戶,在同一個 IIS 執行個體上執行多個網路應用程式時,強制執行本機安全界線。使用 Windows 容器時,每個網頁應用程式都會託管在個別容器中,因此不需要在容器內建立安全界線,因為容器本身就提供安全界線。

即使應用程式集區身分已設定為使用網路服務帳戶,如果應用程式向需要驗證的外部資源提出要求,應用程式也會使用您為 Windows 容器設定的 gMSA 進行驗證。

清除所用資源

如要避免系統向您的 Google Cloud 帳戶收取本教學課程中所用資源的相關費用,請刪除含有該項資源的專案,或者保留專案但刪除個別資源。

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

移除個別資源

如要保留 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. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

  2. 初始化 gcloud 環境:

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

    更改下列內容:

    • PROJECT-ID:您的 Google Cloud 專案 ID。
    • ZONE-NAME:您部署 GKE 叢集和開發 VM 的可用區。
    • LOCATION:部署 Artifact Registry 存放區的區域。
  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. 刪除 Artifact Registry Docker 存放區:

    gcloud artifacts repositories delete windows-container-images --quiet
    

最後,請按照「設定 Active Directory,讓 VM 自動加入網域」一文中的清除步驟操作。

後續步驟