為 Azure Kubernetes Service (AKS) 叢集上的 Windows 伺服器節點,啟用群組受管理的服務帳戶 (GMSA)
群組受管理的服務帳戶 (GMSA) 是多個伺服器的受控網域帳戶,可提供自動密碼管理、簡化的服務主體名稱 (SPN) 管理,以及將管理委派給其他管理員的能力。 藉由 Azure Kubernetes Service (AKS),您可以在 Windows 伺服器節點上啟用 GMSA,並可讓 Windows 伺服器節點上執行的容器,能與 GMSA 整合並透過其管理。
必要條件
- Kubernetes 1.19 或更新版本。 若要檢查您的版本,請參閱檢查是否有可用的升級。 若要升級您的版本,請參閱升級 AKS 叢集。
- Azure CLI 2.35.0 版或更新版本。 執行
az --version
以尋找版本。 如果您需要安裝或升級,請參閱安裝 Azure CLI。 - 在您的 AKS 叢集上啟用受控識別。
- 建立或更新 Azure Key Vault 的權限。
- 在 Active Directory 網域服務,或在內部部署 Active Directory 上,設定 GMSA 的權限。
- 網域控制站必須已經啟用 Active Directory Web 服務,而且必須可透過 AKS 叢集,於連接埠 9389 上連線。
注意
Microsoft 也提供專門建置的 PowerShell 模組,以在 AKS 上設定 gMSA。 如需詳細資訊,請參閱 Azure Kubernetes Service上的 gMSA。
在 Active Directory 網域控制站上設定 GMSA
若要透過 AKS 使用 GMSA,您需要標準網域使用者認證,才能存取網域控制站上設定的 GMSA 認證。 若要在網域控制站上設定 GMSA,請參閱開始使用群組受控服務帳戶。 針對標準網域使用者認證,只要其具有 GMSA 認證的存取權,您即可使用現有的使用者,或建立新的使用者。
重要
您必須使用 Active Directory 網域 Service 或內部部署 Active Directory。 此時,您無法使用 Microsoft Entra ID 設定 GMSA 與 AKS 叢集。
將標準網域使用者認證,儲存於 Azure Key Vault
您的 AKS 叢集會使用標準網域使用者認證,從網域控制站存取 GMSA 認證。 若要為 AKS 叢集提供這些認證的安全存取,您應該將這些儲存在 Azure Key Vault 中。
如果您還沒有 Azure Key Vault,請使用
az keyvault create
命令建立一個。az keyvault create --resource-group myResourceGroup --name myGMSAVault
使用
az keyvault secret set
命令將標準網域使用者認證,儲存為您金鑰保存庫中的祕密。 下列範例會將網域使用者認證與金鑰 GMSADomainUserCred,儲存在 myGMSAVault 金鑰保存庫中。az keyvault secret set --vault-name myGMSAVault --name "GMSADomainUserCred" --value "$Domain\\$DomainUsername:$DomainUserPassword"
注意
務必使用網域的完整網域名稱。
選用:透過自訂 DNS,使用自訂 VNet
您必須透過 DNS 設定域控制器,才能由 AKS 叢集連線。 您可以在 AKS 叢集外部設定網路和 DNS,以允許叢集存取網域控制站。 或者,您可以使用 Azure CNI 對於 AKS 叢集設定具有自訂 DNS 的自訂 VNet,以提供網域控制站的存取權。 如需詳細資訊,請參閱在 Azure Kubernetes Service (AKS) 中設定 Azure CNI 網路。
選用:設定多個 DNS 伺服器
如果您想要在 AKS 叢集中為 Windows GMSA 設定多個 DNS 伺服器,請勿指定 --gmsa-dns-server
或 v--gmsa-root-domain-name
。 不過,您可以選取 [自訂 DNS] 並新增 DNS 伺服器,在 VNet 中新增多個 DNS 伺服器。
選用:針對您的叢集,使用您自己的 kubelet 身分識別
若要提供金鑰保存庫的 AKS 叢集存取權,叢集 kubelet 身分識別需要存取您的金鑰保存庫。 依預設,您建立已啟用受控識別的叢集時,將會自動建立 kubelet 身分識別。
您可以在叢集建立之後,將金鑰保存庫的存取權授與身分識別,也可以使用下列步驟在叢集建立的前建立自己的身分識別:
使用
az identity create
命令建立 kubelet 身分識別。az identity create --name myIdentity --resource-group myResourceGroup
使用
az identity list
命令取得身分識別的識別碼,並將其設定為名為 MANAGED_ID 的變數。MANAGED_ID=$(az identity list --query "[].id" -o tsv)
使用
az keyvault set-policy
命令授與金鑰保存庫的身分識別存取權。az keyvault set-policy --name "myGMSAVault" --object-id $MANAGED_ID --secret-permissions get
在新的 AKS 叢集上啟用 GMSA
建立系統管理員認證,以便在叢集建立期間使用。 下列命令會提示您輸入使用者名稱,並將此設定為 WINDOWS_USERNAME,以供稍後的命令使用。
echo "Please enter the username to use as administrator credentials for Windows Server nodes on your cluster: " && read WINDOWS_USERNAME
使用
az aks create
命令搭配下列參數來建立 AKS 叢集:--enable-windows-gmsa
:啟用叢集的 GMSA。--gmsa-dns-server
:DNS 伺服器的 IP 位址。--gmsa-root-domain-name
:DNS 伺服器的根功能變數名稱。
DNS_SERVER=<IP address of DNS server> ROOT_DOMAIN_NAME="contoso.com" az aks create \ --resource-group myResourceGroup \ --name myAKSCluster \ --vm-set-type VirtualMachineScaleSets \ --network-plugin azure \ --load-balancer-sku standard \ --windows-admin-username $WINDOWS_USERNAME \ --enable-windows-gmsa \ --gmsa-dns-server $DNS_SERVER \ --gmsa-root-domain-name $ROOT_DOMAIN_NAME \ --generate-ssh-keys
注意
如果您使用自訂 VNet,您必須使用
vnet-subnet-id
參數來指定 VNet 識別元,而且您可能需要根據組態新增docker-bridge-address
、dns-service-ip
和service-cidr
參數。如果您為 kubelet 身分識別建立自己的身分識別,請使用
assign-kubelet-identity
參數指定您的身分識別。您指定
--gmsa-dns-server
和--gmsa-root-domain-name
參數時,DNS 轉寄規則會新增至kube-system/coredns
ConfigMap。 此規則會將$ROOT_DOMAIN_NAME
的 DNS 要求從 Pod 轉送至$DNS_SERVER
。$ROOT_DOMAIN_NAME:53 { errors cache 30 log forward . $DNS_SERVER }
使用
az aks nodepool add
命令新增 Windows Server 節點集區。az aks nodepool add \ --resource-group myResourceGroup \ --cluster-name myAKSCluster \ --os-type Windows \ --name npwin \ --node-count 1
在現有叢集上啟用 GMSA
在現有叢集上啟用 GMSA,並使用
az aks update
命令啟用 Windows Server 節點和受控識別。az aks update \ --resource-group myResourceGroup \ --name myAKSCluster \ --enable-windows-gmsa \ --gmsa-dns-server $DNS_SERVER \ --gmsa-root-domain-name $ROOT_DOMAIN_NAME
為 kubelet 身分識別授與金鑰保存庫的存取權
注意
如果您已為 kubelet 身分識別提供自己的身分識別,請略過此步驟。
使用
az keyvault set-policy
命令,為 kubelet 身分識別授與金鑰保存庫的存取權。MANAGED_ID=$(az aks show -g myResourceGroup -n myAKSCluster --query "identityProfile.kubeletidentity.objectId" -o tsv) az keyvault set-policy --name "myGMSAVault" --object-id $MANAGED_ID --secret-permissions get
安裝 GMSA cred 規格
使用
az aks get-credentials
命令,設定kubectl
連線到 Kubernetes 叢集。az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
建立名為 gmsa-spec.yaml 的新 YAML,並貼上下列 YAML。 請務必將預留位置取代為您自己的值。
apiVersion: windows.k8s.io/v1 kind: GMSACredentialSpec metadata: name: aks-gmsa-spec # This name can be changed, but it will be used as a reference in the pod spec credspec: ActiveDirectoryConfig: GroupManagedServiceAccounts: - Name: $GMSA_ACCOUNT_USERNAME Scope: $NETBIOS_DOMAIN_NAME - Name: $GMSA_ACCOUNT_USERNAME Scope: $DNS_DOMAIN_NAME HostAccountConfig: PluginGUID: '{CCC2A336-D7F3-4818-A213-272B7924213E}' PortableCcgVersion: "1" PluginInput: "ObjectId=$MANAGED_ID;SecretUri=$SECRET_URI" # SECRET_URI takes the form https://$akvName.vault.azure.net/secrets/$akvSecretName CmsPlugins: - ActiveDirectory DomainJoinConfig: DnsName: $DNS_DOMAIN_NAME DnsTreeName: $DNS_ROOT_DOMAIN_NAME Guid: $AD_DOMAIN_OBJECT_GUID MachineAccountName: $GMSA_ACCOUNT_USERNAME NetBiosName: $NETBIOS_DOMAIN_NAME Sid: $GMSA_SID
注意
AKS 已在 v20230903 版本中將 GMSACredentialSpec
的 apiVersion
從 windows.k8s.io/v1alpha1
升級為 windows.k8s.io/v1
。
建立名為 gmsa-role.yaml 的新 YAML,並貼上下列 YAML。
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: aks-gmsa-role rules: - apiGroups: ["windows.k8s.io"] resources: ["gmsacredentialspecs"] verbs: ["use"] resourceNames: ["aks-gmsa-spec"]
建立名為 gmsa-role-binding.yaml 的新 YAML,並貼上下列 YAML。
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: allow-default-svc-account-read-on-aks-gmsa-spec namespace: default subjects: - kind: ServiceAccount name: default namespace: default roleRef: kind: ClusterRole name: aks-gmsa-role apiGroup: rbac.authorization.k8s.io
使用
kubectl apply
命令以套用 gmsa-spec.yaml、gmsa-role.yaml,以及 gmsa-role-binding.yaml 的變更。kubectl apply -f gmsa-spec.yaml kubectl apply -f gmsa-role.yaml kubectl apply -f gmsa-role-binding.yaml
確認 GMSA 安裝
建立名為 gmsa-demo.yaml 的新 YAML,並貼上下列 YAML。
--- kind: ConfigMap apiVersion: v1 metadata: labels: app: gmsa-demo name: gmsa-demo namespace: default data: run.ps1: | $ErrorActionPreference = "Stop" Write-Output "Configuring IIS with authentication." # Add required Windows features, since they are not installed by default. Install-WindowsFeature "Web-Windows-Auth", "Web-Asp-Net45" # Create simple ASP.NET page. New-Item -Force -ItemType Directory -Path 'C:\inetpub\wwwroot\app' Set-Content -Path 'C:\inetpub\wwwroot\app\default.aspx' -Value 'Authenticated as <B><%=User.Identity.Name%></B>, Type of Authentication: <B><%=User.Identity.AuthenticationType%></B>' # Configure IIS with authentication. Import-Module IISAdministration Start-IISCommitDelay (Get-IISConfigSection -SectionPath 'system.webServer/security/authentication/windowsAuthentication').Attributes['enabled'].value = $true (Get-IISConfigSection -SectionPath 'system.webServer/security/authentication/anonymousAuthentication').Attributes['enabled'].value = $false (Get-IISServerManager).Sites[0].Applications[0].VirtualDirectories[0].PhysicalPath = 'C:\inetpub\wwwroot\app' Stop-IISCommitDelay Write-Output "IIS with authentication is ready." C:\ServiceMonitor.exe w3svc --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: gmsa-demo name: gmsa-demo namespace: default spec: replicas: 1 selector: matchLabels: app: gmsa-demo template: metadata: labels: app: gmsa-demo spec: securityContext: windowsOptions: gmsaCredentialSpecName: aks-gmsa-spec containers: - name: iis image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019 imagePullPolicy: IfNotPresent command: - powershell args: - -File - /gmsa-demo/run.ps1 volumeMounts: - name: gmsa-demo mountPath: /gmsa-demo volumes: - configMap: defaultMode: 420 name: gmsa-demo name: gmsa-demo nodeSelector: kubernetes.io/os: windows --- apiVersion: v1 kind: Service metadata: labels: app: gmsa-demo name: gmsa-demo namespace: default spec: ports: - port: 80 targetPort: 80 selector: app: gmsa-demo type: LoadBalancer
使用
kubectl apply
命令從 gmsa-demo.yaml 套用變更。kubectl apply -f gmsa-demo.yaml
使用
kubectl get service
命令取得範例應用程式的 IP 位址。kubectl get service gmsa-demo --watch
一開始,
gmsa-demo
服務的EXTERNAL-IP
會顯示為擱置中:NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gmsa-demo LoadBalancer 10.0.37.27 <pending> 80:30572/TCP 6s
EXTERNAL-IP
位址從擱置中變成實際的公用 IP 位址時,請使用CTRL-C
停止kubectl
監看式流程。下列範例輸出顯示指派給服務的有效公用 IP 位址:
gmsa-demo LoadBalancer 10.0.37.27 EXTERNAL-IP 80:30572/TCP 2m
開啟網頁瀏覽器並前往
gmsa-demo
服務的外部 IP 位址。使用
$NETBIOS_DOMAIN_NAME\$AD_USERNAME
和密碼進行驗證,並確認您看到Authenticated as $NETBIOS_DOMAIN_NAME\$AD_USERNAME, Type of Authentication: Negotiate
。
在現有叢集上停用 GMSA
使用
az aks update
命令對於 Windows Server 節點在現有叢集上停用 GMSA。az aks update \ --resource-group myResourceGroup \ --name myAKSCluster \ --disable-windows-gmsa
注意
您可以使用 az aks update 命令,在現有的叢集 上重新啟用 GMSA。
疑難排解
載入頁面時不會提示驗證
如果頁面載入,但並未提示您進行驗證,請使用 kubectl logs POD_NAME
命令顯示 Pod 的記錄,並確認您看到「IIS 驗證已就緒」。
注意
Windows 容器預設不會在 kubectl 上顯示記錄。 若要讓 Windows 容器顯示記錄,您必須在 Windows 映像上內嵌記錄監視器工具。 如需詳細資訊,請參閱「Windows Container Tools」。
嘗試載入頁面時,發生連線逾時
如果您在嘗試載入頁面時收到連線逾時,請確認範例應用程式是使用 kubectl get pods --watch
命令執行。 有時候範例應用程式服務的外部 IP 位址,可在執行範例應用程式 Pod 之前取得。
Pod 無法啟動,而 Pod 事件中會顯示 winapi 錯誤
如果您的 Pod 在執行 kubectl get pods --watch
命令並等候數分鐘後未啟動,請使用 kubectl describe pod POD_NAME
命令。 如果您在 Pod 事件中看到 winapi 錯誤,則可能是 GMSA cred 規格設定中的錯誤。 確認 gmsa-spec.yaml 中的所有取代數值都正確、重新執行 kubectl apply -f gmsa-spec.yaml
,然後重新部署應用程式範例。