Поделиться через


Включение групповых управляемых учетных записей (GMSA) для узлов сервера Windows в кластере Службы Azure Kubernetes (AKS)

Групповые управляемые учетные записи служб (GMSA) — это учетная запись управляемого домена для нескольких серверов, которая обеспечивает автоматическое управление паролями, упрощенное управление именем субъекта-службы и возможность делегировать управление другими администраторами. С помощью Служба Azure Kubernetes (AKS) вы можете включить GMSA на узлах Windows Server, что позволяет контейнерам, работающим на узлах Windows Server, интегрироваться и управлять с помощью GMSA.

Необходимые компоненты

  • Kubernetes 1.19 или более поздней версии. Сведения о проверке версии см. в разделе "Проверка доступных обновлений". Сведения об обновлении версии см. в статье Об обновлении кластера AKS.
  • Azure CLI версии 2.35.0 или выше. Чтобы узнать версию, выполните команду az --version. Если вам необходимо выполнить установку или обновление, см. статью Установка Azure CLI 2.0.
  • Управляемые удостоверения включены в кластере AKS.
  • Разрешения на создание или обновление Azure Key Vault.
  • Разрешения на настройку GMSA в службе домен Active Directory или локальная служба Active Directory.
  • На контроллере домена должны быть включены веб-службы Active Directory, и они должны быть доступны через порт 9389 кластера AKS.

Примечание.

Корпорация Майкрософт также предоставляет специально созданный модуль PowerShell для настройки gMSA в AKS. Дополнительные сведения см. в Служба Azure Kubernetes gMSA.

Настройка GMSA на контроллере домена Active Directory

Чтобы использовать GMSA с AKS, требуется стандартная учетная запись пользователя домена для доступа к учетным данным GMSA, настроенным на контроллере домена. Сведения о настройке GMSA на контроллере домена см. в статье "Начало работы с групповыми управляемыми учетными записями служб". В качестве учетных данных стандартного пользователя домена можно использовать учетные данные существующего пользователя или создать нового с доступом к учетным данным GMSA.

Внимание

Необходимо использовать службу домен Active Directory или локальная служба Active Directory. В настоящее время нельзя использовать идентификатор Microsoft Entra для настройки GMSA с кластером AKS.

Хранение учетных данных стандартного пользователя домена в Azure Key Vault

Кластер AKS использует учетные данные стандартного пользователя домена для доступа к учетным данным GMSA из контроллера домена. Чтобы обеспечить безопасный доступ к этим учетным данным для кластера AKS, их следует хранить в Azure Key Vault.

  1. Если у вас еще нет хранилища ключей Azure, создайте его с помощью az keyvault create команды.

    az keyvault create --resource-group myResourceGroup --name myGMSAVault
    
  2. Сохраните учетные данные пользователя домена уровня "Стандартный" в качестве секрета в хранилище ключей az keyvault secret set с помощью команды. В следующем примере хранятся учетные данные пользователя домена с ключом GMSADomainUserCred в хранилище ключей myGMSAVault .

    az keyvault secret set --vault-name myGMSAVault --name "GMSADomainUserCred" --value "$Domain\\$DomainUsername:$DomainUserPassword"
    

    Примечание.

    Обязательно используйте полное доменное имя для домена.

Необязательно. Использование настраиваемой виртуальной сети с пользовательским DNS

Необходимо настроить контроллер домена через DNS, чтобы он был доступен кластером AKS. Вы можете настроить сеть и DNS за пределами кластера AKS, чтобы разрешить кластеру доступ к контроллеру домена. Кроме того, можно использовать Azure CNI для настройки настраиваемой виртуальной сети с помощью пользовательской DNS-службы в кластере AKS для предоставления доступа к контроллеру домена. Дополнительные сведения см. в разделе "Настройка сети Azure CNI" в Служба Azure Kubernetes (AKS).

Необязательно. Настройка нескольких DNS-серверов

Если вы хотите настроить несколько DNS-серверов для Windows GMSA в кластере AKS, не указывайте или --gmsa-dns-serverне указывайтеv--gmsa-root-domain-name. Вместо этого можно добавить несколько DNS-серверов в виртуальную сеть, выбрав Пользовательский DNS и добавив DNS-серверы.

Необязательно: используйте собственное удостоверение kubelet для кластера

Чтобы у кластера AKS был доступ к вашему хранилищу ключей, этот доступ должен быть у удостоверения kubelet кластера. При создании кластера с включенным управляемым удостоверением удостоверение kubelet автоматически создается по умолчанию.

Вы можете предоставить доступ к хранилищу ключей для удостоверения после создания кластера или создать собственное удостоверение перед созданием кластера, выполнив следующие действия.

  1. Создайте удостоверение kubelet с помощью az identity create команды.

    az identity create --name myIdentity --resource-group myResourceGroup
    
  2. Получите идентификатор удостоверения с помощью az identity list команды и задайте для нее переменную с именем MANAGED_ID.

    MANAGED_ID=$(az identity list --query "[].id" -o tsv)
    
  3. Предоставьте удостоверению доступ к хранилищу ключей az keyvault set-policy с помощью команды.

    az keyvault set-policy --name "myGMSAVault" --object-id $MANAGED_ID --secret-permissions get
    

Включение GMSA в новом кластере AKS

  1. Создайте учетные данные администратора для использования во время создания кластера. Следующая команда запрашивает имя пользователя и задает для него значение WINDOWS_USERNAME для использования в следующей команде.

    echo "Please enter the username to use as administrator credentials for Windows Server nodes on your cluster: " && read WINDOWS_USERNAME
    
  2. Создайте кластер AKS с помощью az aks create команды со следующими параметрами:

    • --enable-windows-gmsa: включает GMSA для кластера.
    • --gmsa-dns-server: IP-адрес DNS-сервера.
    • --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-subnet-id, и в зависимости от конфигурации вам, возможно, придется также добавить параметры docker-bridge-address, dns-service-ip и service-cidr.

    • Если вы создали собственное удостоверение для удостоверения kubelet, используйте assign-kubelet-identity параметр для указания удостоверения.

    • При указании --gmsa-dns-server и --gmsa-root-domain-name параметров правило пересылки DNS добавляется в kube-system/coredns ConfigMap. Это правило перенаправит DNS-запросы $ROOT_DOMAIN_NAME из модулей pod в $DNS_SERVER.

      $ROOT_DOMAIN_NAME:53 {
          errors
          cache 30
          log
          forward . $DNS_SERVER
      }
      
  3. Добавьте пул узлов Windows Server с помощью az aks nodepool add команды.

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --os-type Windows \
        --name npwin \
        --node-count 1
    

Включение GMSA в существующем кластере

  • Включите GMSA в существующем кластере с узлами Windows Server и управляемыми удостоверениями, включенными с помощью az aks update команды.

    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.

  • Предоставьте доступ к хранилищу ключей для удостоверения kubelet с помощью az keyvault set-policy команды.

    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

  1. Настройте kubectl подключение к кластеру az aks get-credentials Kubernetes с помощью команды.

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
    
  2. Создайте yamL с именем gmsa-spec.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 обновила apiVersionGMSACredentialSpec с версии windows.k8s.io/v1alpha1 до версии windows.k8s.io/v1 в выпуске v20230903.

  1. Создайте yamL с именем gmsa-role.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"]
    
  2. Создайте yamL с именем gmsa-role-binding.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
    
  3. Примените изменения из gmsa-spec.yaml, kubectl apply

    kubectl apply -f gmsa-spec.yaml
    kubectl apply -f gmsa-role.yaml
    kubectl apply -f gmsa-role-binding.yaml
    

Проверка установки GMSA

  1. Создайте yamL с именем gmsa-demo.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
    
  2. Примените изменения из gmsa-demo.yaml с помощью kubectl apply команды.

    kubectl apply -f gmsa-demo.yaml
    
  3. Получите IP-адрес примера приложения с помощью kubectl get service команды.

    kubectl get service gmsa-demo --watch
    

    EXTERNAL-IP Изначально служба отображается как ожидающаяgmsa-demo:

    NAME               TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    gmsa-demo          LoadBalancer   10.0.37.27   <pending>     80:30572/TCP   6s
    
  4. EXTERNAL-IP Если адрес изменяется от ожидающего до фактического общедоступного IP-адреса, используйте CTRL-C для остановки kubectl процесса наблюдения.

    В следующем примере выходных данных показан общедоступный IP-адрес, присвоенный службе.

    gmsa-demo  LoadBalancer   10.0.37.27   EXTERNAL-IP   80:30572/TCP   2m
    
  5. Откройте веб-браузер для внешнего IP-адреса gmsa-demo службы.

  6. Проверка подлинности с помощью $NETBIOS_DOMAIN_NAME\$AD_USERNAME пароля и подтверждение.Authenticated as $NETBIOS_DOMAIN_NAME\$AD_USERNAME, Type of Authentication: Negotiate

Отключение GMSA в существующем кластере

  • Отключите GMSA в существующем кластере с узлами Windows Server с помощью az aks update команды.

    az aks update \
        --resource-group myResourceGroup \
        --name myAKSCluster \
        --disable-windows-gmsa
    

Примечание.

Вы можете повторно включить GMSA в существующем кластере с помощью команды az aks update .

Устранение неполадок

При загрузке страницы не выводится запрос на проверку подлинности.

Если страница загружается, но вам не предлагается пройти проверку подлинности, используйте kubectl logs POD_NAME команду для отображения журналов pod и убедитесь, что службы IIS готовы к проверке подлинности.

Примечание.

Контейнеры Windows по умолчанию не отображают журналы в kubectl. Чтобы контейнеры Windows могли отображать журналы, необходимо внедрить средство Log Monitor в образ Windows. Дополнительные сведения см. в разделе "Средства контейнеров Windows".

Время ожидания соединения при попытке загрузить страницу

Если при попытке загрузить страницу вы получите время ожидания подключения, убедитесь, что пример приложения выполняется с помощью kubectl get pods --watch команды. Иногда внешний IP-адрес для примера службы приложений оказывается доступен до запуска примера модуля pod приложения.

Не удается запустить pod, и в событиях pod отображается ошибка winapi

Если модуль pod не запускается после выполнения kubectl get pods --watch команды и ожидает несколько минут, используйте kubectl describe pod POD_NAME команду. Если в событиях pod отображается ошибка winapi, скорее всего, это ошибка в конфигурации спецификации cred GMSA. Убедитесь, что все замененные значения в файле gmsa-spec.yaml правильные, повторно запустите kubectl apply -f gmsa-spec.yaml и разверните пример приложения.

Журналы событий Container Credential Guard показывают ошибки «Служба каталогов недоступна»

Если вы видите это сообщение об ошибке, это может указывать на то, что запросы DNS не проходят из-за блокировки резервного канала TCP.

Если gMSA включена, система выполняет поиск DNS для поиска контроллеров домена, например _ldap._tcp.dc._msdcs.<domain>. В крупных средах Active Directory эти ответы могут превышать ограничение UDP 512-байтов. Когда ограничение UDP достигнуто, DNS-сервер устанавливает флаг усеченного (TC), запрашивая CoreDNS повторить запрос по протоколу TCP, как требуется RFC5966. Этот резервный доступ к TCP является важным для завершения потока проверки подлинности. Если TCP-трафик через порт 53 блокируется группами безопасности сети (NSG) или правилами брандмауэра, то разрешение DNS, и, следовательно, вход gMSA не производится.

Чтобы проверить, возникает ли эта ошибка в вашей среде, включите ведение журнала запросов CoreDNS и используйте kubectl logs --namespace kube-system -l k8s-app=kube-dns команду для просмотра журналов CoreDNS.

Найдите такие закономерности, где ответы UDP обрезаются, а повторные попытки TCP завершаются неудачей.

[INFO] 10.123.123.200:62380 - 2 "ANY IN _ldap._tcp.dc._msdcs.contoso.com. udp 49 false 512" NOERROR qr,aa,tc,rd,ra 1357 0.003399698s
[INFO] 10.123.123.200:64233 - 2 "ANY IN _ldap._tcp.dc._msdcs.contoso.com. tcp 49 false 65535" - - 0 6.009670817s
[ERROR] plugin/errors: 2 _ldap._tcp.dc._msdcs.contoso.com. ANY: read tcp 10.123.123.11:55216-><DNS server IP>:53: i/o timeout

Чтобы устранить эту ошибку, рекомендуется обновить правила NSG или брандмауэра, чтобы явно разрешить трафик DNS через TCP через порт 53. Это обновление обеспечит возможность повторной успешной передачи больших ответов DNS по протоколу TCP, что позволит процессу аутентификации завершиться как ожидалось.

Следующие шаги

Дополнительные сведения см. в рекомендациях по контейнерам Windows с Служба Azure Kubernetes (AKS).