Compartilhar via


Habilitar GMSA (Contas de Serviço Gerenciado de Grupo) para seus nós do Windows Server no cluster do AKS (Serviço de Kubernetes do Azure)

A GMSA (Conta de Serviço Gerenciado de Grupo) é uma conta de domínio gerenciado para vários servidores que fornece gerenciamento automático de senhas, gerenciamento de SPN (nome da entidade de serviço) simplificado e a capacidade de delegar o gerenciamento para outros administradores. Com o AKS (Serviço de Kubernetes do Azure), você pode habilitar o GMSA em seus nós do Windows Server, o que permite que os contêineres em execução em nós do Windows Server se integrem e sejam gerenciados pela GMSA.

Pré-requisitos

  • Kubernetes 1.19 ou posterior. Para verificar sua versão, consulte Verificar se há atualizações disponíveis. Para atualizar sua versão, consulte Atualizar o cluster do AKS.
  • CLI do Azure versão 2.35.0 ou posterior. Para saber qual é a versão, execute az --version. Se você precisa instalar ou atualizar, consulte Instalar a CLI do Azure.
  • Identidades gerenciadas habilitadas no cluster do AKS.
  • Permissões para criar ou atualizar um Azure Key Vault.
  • Permissões para configurar o GMSA no Serviço do Domínio do Active Directory ou no Active Directory local.
  • O controlador de domínio precisa ter os Serviços Web do Active Directory habilitados e precisa estar acessível na porta 9389 pelo cluster do AKS.

Observação

A Microsoft também fornece um módulo do PowerShell criado com a finalidade de configurar o gMSA no AKS. Para obter mais informações, confira GMSA no Serviço de Kubernetes do Azure.

Configurar GMSA no controlador de domínio do Active Directory

Para usar a GMSA com o AKS, você precisa de uma credencial de usuário de domínio padrão para acessar a credencial de GMSA configurada no controlador de domínio. Para configurar a GMSA em seu controlador de domínio, confira Introdução a Contas de Serviço Gerenciado de Grupo. Para a credencial de usuário de domínio padrão, você pode usar um usuário existente ou criar um, desde que ele tenha acesso à credencial GMSA.

Importante

Você precisa usar o Serviço de Domínio do Active Directory ou o Active Directory local. No momento, você não pode usar o Microsoft Entra ID para configurar o GMSA com um cluster do AKS.

Armazene as credenciais de usuário de domínio padrão no Azure Key Vault

O cluster do AKS usa as credenciais de usuário de domínio padrão para acessar as credenciais GMSA do controlador de domínio. Para oferecer acesso seguro a essas credenciais para o cluster do AKS, você deve armazená-las no Azure Key Vault.

  1. Se você ainda não tiver um cofre de chaves do Azure, crie um usando o comando az keyvault create.

    az keyvault create --resource-group myResourceGroup --name myGMSAVault
    
  2. Armazene a credencial de usuário de domínio padrão como um segredo em seu cofre de chaves usando o comando az keyvault secret set. O exemplo a seguir armazena a credencial de usuário do domínio com a chave GMSADomainUserCred no cofre de chaves myGMSAVault.

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

    Observação

    Use o Nome de Domínio Totalmente Qualificado para o domínio.

Opcional: usar uma rede virtual personalizada com DNS personalizado

Você deve configurar seu controlador de domínio através do DNS para que ele seja acessível pelo cluster do AKS. Você pode configurar a rede e o DNS fora do cluster do AKS para permitir que o cluster acesse o controlador de domínio. Como alternativa, você pode usar o CNI do Azure para configurar uma rede virtual personalizada com um DNS personalizado no cluster do AKS para fornecer acesso ao controlador de domínio. Para obter mais informações, consulte Configurar rede a CNI do Azure no Serviço de Kubernetes do Azure.

Opcional: configurar mais de um servidor DNS

Se quiser configurar mais de um servidor DNS para o GMSA do Windows no seu cluster do AKS, não especifique --gmsa-dns-server nem v--gmsa-root-domain-name. Em vez disso, você pode adicionar vários servidores DNS na rede virtual selecionando DNS personalizado e adicionando os servidores DNS.

Opcional: usar sua própria identidade de kubelet para o cluster

Para fornecer ao cluster do AKS acesso ao cofre de chaves, a identidade do kubelet do cluster precisa de acesso ao cofre de chaves. Quando você cria um cluster com a identidade gerenciada habilitada, uma identidade de kubelet é criada automaticamente por padrão.

Você pode conceder acesso ao cofre de chaves para a identidade após a criação do cluster ou criar sua própria identidade para usar antes da criação do cluster usando as seguintes etapas:

  1. Crie uma identidade do kubelet usando o comando az identity create.

    az identity create --name myIdentity --resource-group myResourceGroup
    
  2. Obtenha a ID da identidade usando o comando az identity list e defina-a como uma variável chamada MANAGED_ID.

    MANAGED_ID=$(az identity list --query "[].id" -o tsv)
    
  3. Conceda acesso para a identidade ao cofre de chaves usando o comando az keyvault set-policy.

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

Habilitar a GMSA em um novo cluster do AKS

  1. Crie credenciais de administrador para usar durante a criação do cluster. Os comandos a seguir solicitam um nome de usuário e o definem como WINDOWS_USERNAME para uso em um comando posterior.

    echo "Please enter the username to use as administrator credentials for Windows Server nodes on your cluster: " && read WINDOWS_USERNAME
    
  2. Crie um cluster do AKS usando o comando az aks create com os seguintes parâmetros:

    • --enable-windows-gmsa: habilita a GMSA para o cluster.
    • --gmsa-dns-server: o endereço IP do servidor DNS.
    • --gmsa-root-domain-name: o nome de domínio raiz do servidor 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
    

    Observação

    • Se você estiver usando uma rede virtual personalizada, precisará especificar a ID da rede virtual usando o parâmetro vnet-subnet-id e talvez seja necessário adicionar também os parâmetros docker-bridge-address, dns-service-ip e service-cidr, dependendo da sua configuração.

    • Se você criou sua própria identidade para a identidade do kubelet, use o parâmetro assign-kubelet-identity para especificar sua identidade.

    • Quando você especifica os parâmetros --gmsa-dns-server e --gmsa-root-domain-name os parâmetros, uma regra de encaminhamento DNS é adicionada ao kube-system/coredns ConfigMap. Essa regra encaminha as solicitações DNS do $ROOT_DOMAIN_NAME dos pods para o $DNS_SERVER.

      $ROOT_DOMAIN_NAME:53 {
          errors
          cache 30
          log
          forward . $DNS_SERVER
      }
      
  3. Adicione um pool de nós do Windows Server usando o comando az aks nodepool add.

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

Habilitar a GMSA no cluster existente

  • Habilite a GMSA em um cluster existente com nós do Windows Server e identidades gerenciadas habilitadas usando o comando 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
    

Conceda acesso ao cofre de chaves para a identidade do kubelet

Observação

Ignore essa etapa se você forneceu sua identidade para a identidade do kubelet.

  • Conceda acesso ao cofre de chaves para a identidade do kubelet usando o comando 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
    

Instalar a especificação de credenciais GMSA

  1. Configure o kubectl para se conectar ao cluster do Kubernetes usando o comando az aks get-credentials.

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
    
  2. Crie um novo YAML chamado gmsa-spec.yaml e cole no YAML a seguir. Substitua os espaços reservados pelos seus valores.

    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
    

Observação

O AKS atualizou o apiVersion do GMSACredentialSpec de windows.k8s.io/v1alpha1 para windows.k8s.io/v1 no lançamento v20230903.

  1. Crie um novo YAML chamado gmsa-role.yaml e cole no YAML a seguir.

    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. Crie um novo YAML chamado gmsa-role-binding.yaml e cole no YAML a seguir.

    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. Aplique as alterações de gmsa-spec.yaml, gmsa-role.yaml e gmsa-role-binding.yaml usando o comando kubectl apply.

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

Verificar a instalação da GMSA

  1. Crie um novo YAML chamado gmsa-demo.yaml e cole no YAML a seguir.

    ---
    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. Aplique as alterações de gmsa-demo.yaml usando o comando kubectl apply.

    kubectl apply -f gmsa-demo.yaml
    
  3. Obtenha o endereço IP do aplicativo de exemplo usando o comando kubectl get service.

    kubectl get service gmsa-demo --watch
    

    Inicialmente, o EXTERNAL-IP para o serviço de gmsa-demo é exibido como pendente:

    NAME               TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    gmsa-demo          LoadBalancer   10.0.37.27   <pending>     80:30572/TCP   6s
    
  4. Quando o endereço EXTERNAL-IP for alterado de pendente para um endereço IP público real, use CTRL-C para interromper o processo de inspeção do kubectl.

    A seguinte saída de exemplo mostra um endereço IP público válido atribuído ao serviço:

    gmsa-demo  LoadBalancer   10.0.37.27   EXTERNAL-IP   80:30572/TCP   2m
    
  5. Abra um navegador da Web para o endereço IP externo do serviço de gmsa-demo.

  6. Autentique com $NETBIOS_DOMAIN_NAME\$AD_USERNAME e a senha e confirme se você vê Authenticated as $NETBIOS_DOMAIN_NAME\$AD_USERNAME, Type of Authentication: Negotiate.

Habilitar a GMSA no cluster existente

  • Habilite a GMSA em um cluster existente com nós do Windows Server usando o comando az aks update.

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

Observação

Você pode reabilitar a GMSA em um cluster existente usando o comando az aks update.

Solução de problemas

Nenhuma autenticação é solicitada ao carregar a página

Se a página for carregada, mas você não for solicitado a autenticar, use o comando kubectl logs POD_NAME para exibir os logs do pod e verificar se você vê o IIS com autenticação está pronto.

Observação

Os contêineres do Windows não mostram logs no kubectl por padrão. Para permitir que os contêineres do Windows mostrem logs, você precisa inserir a ferramenta Monitor de Log na imagem do Windows. Para obter mais informações, confira Ferramentas de Contêineres do Windows.

Tempo limite da conexão atingido ao tentar carregar a página

Se você receber uma mensagem de tempo limite de conexão ao tentar carregar a página, verifique se o aplicativo de exemplo está em execução usando o comando kubectl get pods --watch. Às vezes, o endereço IP externo para o serviço de aplicativo de exemplo está disponível antes de o pod do aplicativo de exemplo ser executado.

O pod falha em iniciar e um erro winapi aparece nos eventos de pod

Se o pod não começar depois de executar o comando kubectl get pods --watch e aguardar vários minutos, use o comando kubectl describe pod POD_NAME. Se você vir um erro winapi nos eventos de pod, provavelmente é um erro na configuração de especificação de credenciais GMSA. Verifique se todos os valores de substituição em gmsa-spec.yaml estão corretos, execute kubectl apply -f gmsa-spec.yaml novamente e reimplante o aplicativo de exemplo.

Os logs de eventos do Credential Guard de Contêiner mostram erros de Serviço de Diretório não disponível

Se você vir essa mensagem de erro, pode indicar que as consultas DNS estão falhando devido a um bloqueio na retomada por TCP.

Quando a gMSA está habilitada, o sistema executa pesquisas de DNS para localizar controladores de domínio, por exemplo _ldap._tcp.dc._msdcs.<domain>. Em ambientes grandes do Active Directory, essas respostas podem exceder o limite de UDP de 512 bytes. Quando o limite de UDP é atingido, o servidor DNS define o sinalizador TC truncado, solicitando que o CoreDNS repita a consulta por TCP, conforme exigido pelo RFC5966. Esse fallback para TCP é essencial para concluir o fluxo de autenticação. Se o tráfego TCP na porta 53 for bloqueado por NSG (grupo de segurança de rede) ou regras de firewall, a resolução DNS e, portanto, o logon gMSA falhará.

Para verificar se esse erro está ocorrendo em seu ambiente, habilite o log de consultas CoreDNS e use o kubectl logs --namespace kube-system -l k8s-app=kube-dns comando para exibir logs do CoreDNS.

Procure padrões como este, em que as respostas UDP são truncadas e as novas tentativas de TCP falham:

[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

Para resolver esse erro, recomendamos atualizar o NSG ou as regras de firewall para permitir explicitamente o tráfego DNS por TCP na porta 53. Essa atualização garantirá que respostas DNS grandes possam ser repetidas com êxito por TCP, permitindo que o fluxo de autenticação seja concluído conforme o esperado.

Próximas etapas

Para mais informações, consulte Considerações sobre contêineres do Windows no Serviço de Kubernetes do Azure (AKS).