Implantar e configurar a identidade da carga de trabalho em um cluster do Serviço Kubernetes do Azure (AKS)

O Serviço Kubernetes do Azure (AKS) é um serviço Kubernetes gerenciado que permite implantar e gerenciar clusters Kubernetes rapidamente. Este artigo mostra-lhe como:

  • Implante um cluster AKS usando a CLI do Azure com o emissor do OpenID Connect e uma ID de carga de trabalho do Microsoft Entra.
  • Crie um ID de carga de trabalho do Microsoft Entra e uma conta de serviço do Kubernetes.
  • Configure a identidade gerenciada para federação de tokens.
  • Implante a carga de trabalho e verifique a autenticação com a identidade da carga de trabalho.
  • Opcionalmente, conceda a um pod no cluster acesso a segredos em um cofre de chaves do Azure.

Este artigo pressupõe que você tenha uma compreensão básica dos conceitos do Kubernetes. Para obter mais informações, consulte Conceitos principais do Kubernetes para o Serviço Kubernetes do Azure (AKS). Se você não estiver familiarizado com o ID de carga de trabalho do Microsoft Entra, consulte o seguinte artigo Visão geral .

Pré-requisitos

Nota

Você pode usar o Service Connector para ajudá-lo a configurar algumas etapas automaticamente. Consulte também: Tutorial: Conectar-se à conta de armazenamento do Azure no Serviço Kubernetes do Azure (AKS) com o Service Connector usando a identidade da carga de trabalho.

Definir a subscrição ativa

Primeiro, defina sua assinatura como a assinatura ativa atual chamando o comando az account set e passando sua ID de assinatura.

az account set --subscription <subscription-id>

Exportar variáveis de ambiente

Para ajudar a simplificar as etapas para configurar as identidades necessárias, as etapas abaixo definem as variáveis de ambiente que são referenciadas nos exemplos deste artigo. Lembre-se de substituir os valores mostrados pelos seus próprios valores:

export RESOURCE_GROUP="myResourceGroup"
export LOCATION="eastus"
export CLUSTER_NAME="myAKSCluster"
export SERVICE_ACCOUNT_NAMESPACE="default"
export SERVICE_ACCOUNT_NAME="workload-identity-sa"
export SUBSCRIPTION="$(az account show --query id --output tsv)"
export USER_ASSIGNED_IDENTITY_NAME="myIdentity"
export FEDERATED_IDENTITY_CREDENTIAL_NAME="myFedIdentity"
# Include these variables to access key vault secrets from a pod in the cluster.
export KEYVAULT_NAME="keyvault-workload-id"
export KEYVAULT_SECRET_NAME="my-secret"

Criar um grupo de recursos

Um grupo de recursos do Azure é um grupo lógico no qual os recursos do Azure são implantados e gerenciados. Ao criar um grupo de recursos, você será solicitado a especificar um local. Esse local é o local de armazenamento dos metadados do grupo de recursos e onde os recursos são executados no Azure se você não especificar outra região durante a criação do recurso.

Crie um grupo de recursos chamando o comando az group create :

az group create --name "${RESOURCE_GROUP}" --location "${LOCATION}"

O exemplo de saída a seguir mostra a criação bem-sucedida de um grupo de recursos:

{
  "id": "/subscriptions/<guid>/resourceGroups/myResourceGroup",
  "location": "eastus",
  "managedBy": null,
  "name": "myResourceGroup",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null
}

Criar um cluster do AKS

Crie um cluster AKS usando o comando az aks create com o --enable-oidc-issuer parâmetro para habilitar o emissor OIDC. O exemplo a seguir cria um cluster com um único nó:

az aks create \
    --resource-group "${RESOURCE_GROUP}" \
    --name "${CLUSTER_NAME}" \
    --enable-oidc-issuer \
    --enable-workload-identity \
    --generate-ssh-keys

Após alguns minutos, o comando conclui e retorna informações formatadas em JSON sobre o cluster.

Nota

Quando você cria um cluster AKS, um segundo grupo de recursos é criado automaticamente para armazenar os recursos do AKS. Para obter mais informações, consulte Por que dois grupos de recursos são criados com o AKS?.

Atualizar um cluster AKS existente

Você pode atualizar um cluster AKS para usar o emissor OIDC e habilitar a identidade da carga de trabalho chamando o comando az aks update com os --enable-oidc-issuer parâmetros e --enable-workload-identity . O exemplo a seguir atualiza um cluster existente:

az aks update \
    --resource-group "${RESOURCE_GROUP}" \
    --name "${CLUSTER_NAME}" \
    --enable-oidc-issuer \
    --enable-workload-identity

Recuperar o URL do emissor OIDC

Para obter a URL do emissor OIDC e salvá-la em uma variável ambiental, execute o seguinte comando:

export AKS_OIDC_ISSUER="$(az aks show --name "${CLUSTER_NAME}" \
    --resource-group "${RESOURCE_GROUP}" \
    --query "oidcIssuerProfile.issuerUrl" \
    --output tsv)"

A variável de ambiente deve conter a URL do emissor, semelhante ao exemplo a seguir:

https://eastus.oic.prod-aks.azure.com/00000000-0000-0000-0000-000000000000/11111111-1111-1111-1111-111111111111/

Por padrão, o emissor é definido para usar a URL https://{region}.oic.prod-aks.azure.com/{tenant_id}/{uuid}base, onde o valor for {region} corresponde ao local no qual o cluster AKS está implantado. O valor {uuid} representa a chave OIDC, que é um guid gerado aleatoriamente para cada cluster que é imutável.

Criar uma identidade gerenciada

Chame o comando az identity create para criar uma identidade gerenciada.

az identity create \
    --name "${USER_ASSIGNED_IDENTITY_NAME}" \
    --resource-group "${RESOURCE_GROUP}" \
    --location "${LOCATION}" \
    --subscription "${SUBSCRIPTION}"

Em seguida, crie uma variável para o ID do cliente da identidade gerenciada.

export USER_ASSIGNED_CLIENT_ID="$(az identity show \
    --resource-group "${RESOURCE_GROUP}" \
    --name "${USER_ASSIGNED_IDENTITY_NAME}" \
    --query 'clientId' \
    --output tsv)"

Criar uma conta de serviço do Kubernetes

Crie uma conta de serviço Kubernetes e anote-a com o ID do cliente da identidade gerenciada criada na etapa anterior. Use o comando az aks get-credentials e substitua os valores do nome do cluster e do nome do grupo de recursos.

az aks get-credentials --name "${CLUSTER_NAME}" --resource-group "${RESOURCE_GROUP}"

Copie e cole a seguinte entrada de várias linhas na CLI do Azure.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    azure.workload.identity/client-id: "${USER_ASSIGNED_CLIENT_ID}"
  name: "${SERVICE_ACCOUNT_NAME}"
  namespace: "${SERVICE_ACCOUNT_NAMESPACE}"
EOF

A saída a seguir mostra a criação bem-sucedida da identidade da carga de trabalho:

serviceaccount/workload-identity-sa created

Criar a credencial de identidade federada

Chame o comando az identity federated-credential create para criar a credencial de identidade federada entre a identidade gerenciada, o emissor da conta de serviço e o assunto. Para obter mais informações sobre credenciais de identidade federada no Microsoft Entra, consulte Visão geral das credenciais de identidade federada no Microsoft Entra ID.

az identity federated-credential create \
    --name ${FEDERATED_IDENTITY_CREDENTIAL_NAME} \
    --identity-name "${USER_ASSIGNED_IDENTITY_NAME}" \
    --resource-group "${RESOURCE_GROUP}" \
    --issuer "${AKS_OIDC_ISSUER}" \
    --subject system:serviceaccount:"${SERVICE_ACCOUNT_NAMESPACE}":"${SERVICE_ACCOUNT_NAME}" \
    --audience api://AzureADTokenExchange

Nota

Leva alguns segundos para que a credencial de identidade federada se propague depois de ser adicionada. Se uma solicitação de token for feita imediatamente após a adição da credencial de identidade federada, a solicitação poderá falhar até que o cache seja atualizado. Para evitar esse problema, você pode adicionar um pequeno atraso após adicionar a credencial de identidade federada.

Implementar a sua aplicação

Quando você implanta seus pods de aplicativo, o manifesto deve fazer referência à conta de serviço criada na etapa Criar conta de serviço do Kubernetes. O manifesto a seguir mostra como fazer referência à conta, especificamente as propriedades metadata\namespace e spec\serviceAccountName . Certifique-se de especificar uma imagem para <image> e um nome de contêiner para <containerName>:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: sample-workload-identity
  namespace: ${SERVICE_ACCOUNT_NAMESPACE}
  labels:
    azure.workload.identity/use: "true"  # Required. Only pods with this label can use workload identity.
spec:
  serviceAccountName: ${SERVICE_ACCOUNT_NAME}
  containers:
    - image: <image>
      name: <containerName>
EOF

Importante

Certifique-se de que os pods de aplicativo que usam a identidade da carga de trabalho incluam o rótulo azure.workload.identity/use: "true" na especificação do pod. Caso contrário, os pods falharão depois de serem reiniciados.

Conceder permissões para acessar o Azure Key Vault

As instruções nesta etapa mostram como acessar segredos, chaves ou certificados em um cofre de chaves do Azure a partir do pod. Os exemplos nesta seção configuram o acesso a segredos no cofre de chaves para a identidade da carga de trabalho, mas você pode executar etapas semelhantes para configurar o acesso a chaves ou certificados.

O exemplo a seguir mostra como usar o modelo de permissão de controle de acesso baseado em função do Azure (Azure RBAC) para conceder acesso ao pod ao cofre de chaves. Para obter mais informações sobre o modelo de permissão do Azure RBAC para o Azure Key Vault, consulte Conceder permissão a aplicativos para acessar um cofre de chaves do Azure usando o Azure RBAC.

  1. Crie um cofre de chaves com proteção contra limpeza e autorização RBAC habilitada. Você também pode usar um cofre de chaves existente se ele estiver configurado para proteção contra limpeza e autorização RBAC:

    export KEYVAULT_RESOURCE_GROUP="myResourceGroup"
    export KEYVAULT_NAME="myKeyVault"
    
    az keyvault create \
        --name "${KEYVAULT_NAME}" \
        --resource-group "${KEYVAULT_RESOURCE_GROUP}" \
        --location "${LOCATION}" \
        --enable-purge-protection \
        --enable-rbac-authorization
    
  2. Atribua a si mesmo a função de Oficial de Segredos do Cofre de Chaves RBAC para que você possa criar um segredo no novo cofre de chaves:

    export KEYVAULT_RESOURCE_ID=$(az keyvault show --resource-group "${KEYVAULT_RESOURCE_GROUP}" \
        --name "${KEYVAULT_NAME}" \
        --query id \
        --output tsv)
    
    az role assignment create --assignee "\<user-email\>" \
        --role "Key Vault Secrets Officer" \
        --scope "${KEYVAULT_RESOURCE_ID}"
    
  3. Crie um segredo no cofre de chaves:

    export KEYVAULT_SECRET_NAME="my-secret"
    
    az keyvault secret set \
        --vault-name "${KEYVAULT_NAME}" \
        --name "${KEYVAULT_SECRET_NAME}" \
        --value "Hello\!"
    
  4. Atribua a função Usuário de Segredos do Cofre de Chaves à identidade gerenciada atribuída pelo usuário que você criou anteriormente. Esta etapa dá à identidade gerenciada permissão para ler segredos do cofre de chaves:

    export IDENTITY_PRINCIPAL_ID=$(az identity show \
        --name "${USER_ASSIGNED_IDENTITY_NAME}" \
        --resource-group "${RESOURCE_GROUP}" \
        --query principalId \
        --output tsv)
    
    az role assignment create \
        --assignee-object-id "${IDENTITY_PRINCIPAL_ID}" \
        --role "Key Vault Secrets User" \
        --scope "${KEYVAULT_RESOURCE_ID}" \
        --assignee-principal-type ServicePrincipal
    
  5. Crie uma variável de ambiente para o URL do cofre de chaves:

    export KEYVAULT_URL="$(az keyvault show \
        --resource-group ${KEYVAULT_RESOURCE_GROUP} \
        --name ${KEYVAULT_NAME} \
        --query properties.vaultUri \
        --output tsv)"
    
  6. Implante um pod que faça referência à conta de serviço e ao URL do cofre de chaves:

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-workload-identity-key-vault
      namespace: ${SERVICE_ACCOUNT_NAMESPACE}
      labels:
        azure.workload.identity/use: "true"
    spec:
      serviceAccountName: ${SERVICE_ACCOUNT_NAME}
      containers:
        - image: ghcr.io/azure/azure-workload-identity/msal-go
          name: oidc
          env:
          - name: KEYVAULT_URL
            value: ${KEYVAULT_URL}
          - name: SECRET_NAME
            value: ${KEYVAULT_SECRET_NAME}
      nodeSelector:
        kubernetes.io/os: linux
    EOF
    

Para verificar se todas as propriedades são injetadas corretamente pelo webhook, use o comando kubectl describe :

kubectl describe pod sample-workload-identity-key-vault | grep "SECRET_NAME:"

Se for bem-sucedida, a saída deve ser semelhante à seguinte:

      SECRET_NAME:                 ${KEYVAULT_SECRET_NAME}

Para verificar se o pod é capaz de obter um token e acessar o recurso, use o comando kubectl logs:

kubectl logs sample-workload-identity-key-vault

Se for bem-sucedida, a saída deve ser semelhante à seguinte:

I0114 10:35:09.795900       1 main.go:63] "successfully got secret" secret="Hello\\!"

Importante

As atribuições de função do RBAC do Azure podem levar até dez minutos para se propagar. Se o pod não conseguir acessar o segredo, talvez seja necessário aguardar a propagação da atribuição de função. Para obter mais informações, consulte Solucionar problemas do Azure RBAC.

Desabilitar a identidade da carga de trabalho

Para desativar o ID de carga de trabalho do Microsoft Entra no cluster AKS onde ele foi habilitado e configurado, você pode executar o seguinte comando:

az aks update \
    --resource-group "${RESOURCE_GROUP}" \
    --name "${CLUSTER_NAME}" \
    --disable-workload-identity

Próximos passos

Neste artigo, você implantou um cluster Kubernetes e o configurou para usar uma identidade de carga de trabalho em preparação para cargas de trabalho de aplicativo para autenticação com essa credencial. Agora você está pronto para implantar seu aplicativo e configurá-lo para usar a identidade da carga de trabalho com a versão mais recente da biblioteca de cliente do Azure Identity . Se não for possível reescrever seu aplicativo para usar a versão mais recente da biblioteca do cliente, você poderá configurar seu pod de aplicativo para autenticar usando identidade gerenciada com identidade de carga de trabalho como uma solução de migração de curto prazo.

A integração do Service Connector ajuda a simplificar a configuração de conexão para cargas de trabalho AKS e serviços de suporte do Azure. Ele lida com segurança com autenticação e configurações de rede e segue as práticas recomendadas para se conectar aos serviços do Azure. Para obter mais informações, consulte Conectar-se ao Serviço OpenAI do Azure no AKS usando a Identidade da Carga de Trabalho e a introdução do Service Connector.