Microsoft Entra Workload-id implementeren en configureren op een Azure Kubernetes Service (AKS)-cluster

In dit artikel leert u hoe u een Azure Kubernetes Service (AKS)-cluster implementeert en configureert met Microsoft Entra Workload-id. De stappen in dit artikel zijn onder andere:

  • Maak een nieuw AKS-cluster of werk een bestaand AKS-cluster bij met behulp van de Azure CLI of Terraform met OIDC-verlener (OpenID Connect) en Microsoft Entra Workload-id ingeschakeld.
  • Maak een workload-identiteit en een Kubernetes-serviceaccount.
  • Configureer de beheerde identiteit voor tokenfederatie.
  • Implementeer de workload en controleer de authenticatie met de workload-identiteit.
  • U kunt desgewenst een pod in het cluster toegang verlenen tot geheimen in een Azure sleutelkluis.

Vereisten

  • Als u geen Azure account hebt, maakt u een free-account voordat u begint.
  • Voor dit artikel is versie 2.47.0 of hoger van de Azure CLI vereist. Als u Azure Cloud Shell gebruikt, is de nieuwste versie al geïnstalleerd. Voer az --version uit om de versie te vinden. Zie Install Azure CLI als u de Azure CLI wilt installeren of upgraden.
  • Zorg ervoor dat de identiteit die u gebruikt om uw cluster te maken over de juiste minimale machtigingen beschikt. Zie Access- en identiteitsopties voor Azure Kubernetes Service (AKS) voor meer informatie.
  • Als u meerdere Azure abonnementen hebt, selecteert u de juiste abonnements-id waarin de resources moeten worden gefactureerd met behulp van de opdracht az account set.

Notitie

U kunt serviceconnector gebruiken om bepaalde stappen automatisch te configureren. Zie Tutorial: Verbinding maken met Azure opslagaccount in Azure Kubernetes Service (AKS) met serviceconnector met behulp van Microsoft Entra Workload-id voor meer informatie.

Het Terraform-configuratiebestand maken

Terraform-configuratiebestanden definiëren de infrastructuur die Terraform maakt en beheert.

  1. Maak een bestand met de naam main.tf en voeg de volgende code toe om de Terraform-versie te definiëren en geef de Azure-provider op:

    terraform {
     required_version = ">= 1.5.0"
     required_providers {
       azurerm = {
         source  = "hashicorp/azurerm"
         version = "~> 4.0"
       }
       kubernetes = {
         source  = "hashicorp/kubernetes"
         version = "~> 2.30"
       }
       random = {
         source  = "hashicorp/random"
         version = "~> 3.6"
       }
     }
    }
    provider "azurerm" {
     features {}
     subscription_id = var.subscription_id
    }
    data "azurerm_client_config" "current" {}
    
  2. Voeg de volgende code toe aan main.tf om herbruikbare variabelen te definiëren en unieke namen te genereren voor alle resources:

    resource "random_string" "suffix" {
     length  = 6
     upper   = false
     special = false
     numeric = true
    }
    locals {
     suffix = random_string.suffix.result
     resource_group_name       = "rg-aks-wi-${local.suffix}"
     cluster_name              = "akswi${local.suffix}"
     managed_identity_name     = "uami-wi-${local.suffix}"
     federated_credential_name = "fic-wi-${local.suffix}"
     key_vault_name            = lower(substr("kvwi${local.suffix}", 0, 24))
     secret_name               = "secret-${local.suffix}"
     service_account_name      = "workload-sa-${local.suffix}"
     service_account_namespace = "default"
     workload_identity_subject = "system:serviceaccount:${local.service_account_namespace}:${local.service_account_name}"
    }
    

Een brongroep maken

Maak een resourcegroep met behulp van de az group create opdracht.

export RANDOM_ID="$(openssl rand -hex 3)"
export RESOURCE_GROUP="myResourceGroup$RANDOM_ID"
export LOCATION="<your-preferred-region>"
az group create --name "${RESOURCE_GROUP}" --location "${LOCATION}"

Voeg de volgende code toe aan main.tf om een Azure resourcegroep te maken. Werk de location-waarde bij zodat deze overeenkomt met de gewenste Azure regio.

resource "azurerm_resource_group" "this" {
 name     = local.resource_group_name
 location = "eastus"
}

OIDC-verlener en Microsoft Entra Workload-id inschakelen op een AKS-cluster

U kunt OIDC-verlener en Microsoft Entra Workload-id inschakelen op een nieuw of bestaand AKS-cluster.

Maak een AKS-cluster met behulp van de opdracht az aks create met de parameter --enable-oidc-issuer om OIDC-verlener en de parameter --enable-workload-identity in te schakelen om Microsoft Entra Workload-id in te schakelen. In het volgende voorbeeld wordt een cluster met één knooppunt gemaakt:

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

Na enkele minuten is de opdracht voltooid en retourneert deze informatie over het cluster in JSON-indeling.

Voeg de volgende code toe aan main.tf om een AKS-cluster te maken met OIDC-verlener en Microsoft Entra Workload-id ingeschakeld:

resource "azurerm_kubernetes_cluster" "this" {
 name                              = local.cluster_name
 location                          = azurerm_resource_group.this.location
 resource_group_name               = azurerm_resource_group.this.name
 dns_prefix                        = local.cluster_name
 oidc_issuer_enabled               = true
 workload_identity_enabled         = true
 role_based_access_control_enabled = true
 default_node_pool {
   name       = "system"
   node_count = 1
   vm_size    = "Standard_B4ms"
 }
 identity {
   type = "SystemAssigned"
 }
}

De URL van de OIDC-verlener ophalen

Haal de URL van de OIDC-verlener op met behulp van de az aks show opdracht en sla deze op in een omgevingsvariabele.

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

De omgevingsvariabele moet de URL van de verlener bevatten, vergelijkbaar met het volgende voorbeeld:

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

De issuer is standaard ingesteld om de basis-URL https://{region}.oic.prod-aks.azure.com/{tenant_id}/{uuid} te gebruiken, waarbij de waarde voor {region} overeenkomt met de locatie waar het AKS-cluster is geïmplementeerd. De waarde {uuid} vertegenwoordigt de OIDC-sleutel, een willekeurig gegenereerde en onveranderbare GUID voor elk cluster.

Voeg de volgende code toe aan main.tf om de issuer-URL van de OIDC-verlener op te halen:

output "oidc_issuer_url" {
 value = azurerm_kubernetes_cluster.this.oidc_issuer_url
}

Een beheerde identiteit maken

  1. Haal uw abonnements-id op en sla deze op in een omgevingsvariabele met behulp van de az account show opdracht.

    export SUBSCRIPTION="$(az account show --query id --output tsv)"
    
  2. Maak een door de gebruiker toegewezen beheerde identiteit met behulp van de az identity create opdracht.

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

    In het volgende uitvoervoorbeeld ziet u hoe een beheerde identiteit is gemaakt:

    {
      "clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/myResourceGroupxxxxxx/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentityxxxxxx",
      "location": "eastus",
      "name": "myIdentityxxxxxx",
      "principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "resourceGroup": "myResourceGroupxxxxxx",
      "systemData": null,
      "tags": {},
      "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "type": "Microsoft.ManagedIdentity/userAssignedIdentities"
    }
    
  3. Haal de client-id van de beheerde identiteit op en sla deze op in een omgevingsvariabele met behulp van de az identity show opdracht.

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

Voeg de volgende code main.tf toe om een beheerde identiteit te maken.

resource "azurerm_user_assigned_identity" "this" {
 name                = local.managed_identity_name
 location            = azurerm_resource_group.this.location
 resource_group_name = azurerm_resource_group.this.name
}

Een Kubernetes-serviceaccount maken

  1. Maak verbinding met uw AKS-cluster met behulp van de az aks get-credentials opdracht.

    az aks get-credentials --name "${CLUSTER_NAME}" --resource-group "${RESOURCE_GROUP}"
    
  2. Maak een Kubernetes-serviceaccount en annotaeer dit met de client-id van de beheerde identiteit door het volgende manifest toe te passen met behulp van de kubectl apply opdracht.

    export SERVICE_ACCOUNT_NAME="workload-identity-sa$RANDOM_ID"
    export SERVICE_ACCOUNT_NAMESPACE="default"
    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
    

    De volgende uitvoer toont de succesvolle aanmaak van de workloadidentiteit.

    serviceaccount/workload-identity-sa created
    
  1. Voeg de volgende code toe aan main.tf om Kubernetes-toegang te configureren voor het maken van Kubernetes-resources:

    data "azurerm_kubernetes_cluster" "this" {
     name                = azurerm_kubernetes_cluster.this.name
     resource_group_name = azurerm_resource_group.this.name
    }
    provider "kubernetes" {
     host                   = data.azurerm_kubernetes_cluster.this.kube_config[0].host
     client_certificate     = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].client_certificate)
     client_key             = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].client_key)
     cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].cluster_ca_certificate)
    }
    
  2. Voeg de volgende code toe aan main.tf om een Kubernetes-serviceaccount te maken en deze te annoteren met de client-id van de beheerde identiteit.

    resource "kubernetes_service_account" "this" {
     metadata {
       name      = local.service_account_name
       namespace = local.service_account_namespace
       annotations = {
         "azure.workload.identity/client-id" = azurerm_user_assigned_identity.this.client_id
       }
     }
    }
    

Maak de federatieve identiteitsreferentie

Maak een federatieve identiteitsreferentie tussen de beheerde identiteit, de verlener van het serviceaccount en het onderwerp met behulp van de az identity federated-credential create opdracht.

export FEDERATED_IDENTITY_CREDENTIAL_NAME="myFedIdentity$RANDOM_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

Notitie

Het duurt enkele seconden voordat een federatieve identiteitsreferentie zich heeft verspreid nadat deze is toegevoegd. Als er direct na het toevoegen van de federatieve identiteitsreferentie een tokenaanvraag wordt gedaan, mislukt de aanvraag mogelijk totdat de cache wordt vernieuwd. U kunt dit probleem voorkomen door een kleine vertraging toe te voegen nadat u de federatieve identiteitsreferentie hebt toegevoegd.

Voeg de volgende code toe aan main.tf om een federatieve identiteitsreferentie aan te maken tussen de beheerde identiteit, de verlener van het serviceaccount en het onderwerp:

resource "azurerm_federated_identity_credential" "this" {
 name                = local.federated_credential_name
 resource_group_name = azurerm_resource_group.this.name
 parent_id           = azurerm_user_assigned_identity.this.id
 issuer              = azurerm_kubernetes_cluster.this.oidc_issuer_url
 subject             = local.workload_identity_subject
 audience            = ["api://AzureADTokenExchange"]
}

Zie Overview van federatieve identiteitsreferenties in Microsoft Entra ID voor meer informatie over federatieve identiteitsreferenties in Microsoft Entra.

Een sleutelkluis maken met Azure RBAC-autorisatie

In het volgende voorbeeld ziet u hoe u het machtigingsmodel Azure op rollen gebaseerd toegangsbeheer (Azure RBAC) gebruikt om de pod toegang te verlenen tot de sleutelkluis. Zie voor meer informatie over het Azure RBAC-machtigingsmodel voor Azure Key Vault Grant-machtiging voor toepassingen voor toegang tot een Azure key vault met Azure RBAC.

  1. Maak een sleutelkluis met opschoningsbeveiliging en Azure RBAC-autorisatie ingeschakeld met behulp van de opdracht az keyvault create. U kunt ook een bestaande sleutelkluis gebruiken als deze is geconfigureerd voor zowel beveiliging tegen opschonen als Azure RBAC-autorisatie.

    export KEYVAULT_NAME="keyvault-workload-id$RANDOM_ID" # Ensure the key vault name is between 3-24 characters
    az keyvault create \
        --name "${KEYVAULT_NAME}" \
        --resource-group "${RESOURCE_GROUP}" \
        --location "${LOCATION}" \
        --enable-purge-protection \
        --enable-rbac-authorization
    
  2. Haal de resource-id van de sleutelkluis op en sla deze op in een omgevingsvariabele met behulp van de az keyvault show opdracht.

    export KEYVAULT_RESOURCE_ID=$(az keyvault show --resource-group "${RESOURCE_GROUP}" \
        --name "${KEYVAULT_NAME}" \
        --query id \
        --output tsv)
    

Voeg de volgende code toe aan main.tf om een sleutelkluis te maken met Azure RBAC-autorisatie:

resource "azurerm_key_vault" "this" {
 name                          = local.key_vault_name
 location                      = azurerm_resource_group.this.location
 resource_group_name           = azurerm_resource_group.this.name
 tenant_id                     = data.azurerm_client_config.current.tenant_id
 sku_name                      = "standard"
 rbac_authorization_enabled    = true
}

RBAC-machtigingen toewijzen voor sleutelkluisbeheer

  1. Haal de object-id van de aanroeper op en sla deze op in een omgevingsvariabele met behulp van de az ad signed-in-user show opdracht.

    export CALLER_OBJECT_ID=$(az ad signed-in-user show --query id -o tsv)
    
  2. Wijs uzelf de rol Azure RBAC Key Vault Secrets Officer toe, zodat u een geheim in de nieuwe key vault kunt maken met behulp van de opdracht az role assignment create.

    az role assignment create --assignee "${CALLER_OBJECT_ID}" \
        --role "Key Vault Secrets Officer" \
        --scope "${KEYVAULT_RESOURCE_ID}"
    

Voeg de volgende code toe aan main.tf om uzelf de rol Azure RBAC Key Vault Secrets Officer toe te wijzen, zodat u een geheim kunt maken in de nieuwe key vault en de rol Key Vault Secrets User kunt toewijzen aan de door de gebruiker toegewezen beheerde identiteit:

resource "azurerm_role_assignment" "user" {
 scope                = azurerm_key_vault.this.id
 role_definition_name = "Key Vault Secrets Officer"
 principal_id         = data.azurerm_client_config.current.object_id
}
resource "azurerm_role_assignment" "identity" {
 scope                = azurerm_key_vault.this.id
 role_definition_name = "Key Vault Secrets User"
 principal_id         = azurerm_user_assigned_identity.this.principal_id
}

Geheime toegang maken en configureren

  1. Maak een geheim in de sleutelkluis met behulp van de az keyvault secret set opdracht.

    export KEYVAULT_SECRET_NAME="my-secret$RANDOM_ID"
    az keyvault secret set \
        --vault-name "${KEYVAULT_NAME}" \
        --name "${KEYVAULT_SECRET_NAME}" \
        --value "Hello\!"
    
  2. Haal de principal-id van de door de gebruiker toegewezen beheerde identiteit op en sla deze op in een omgevingsvariabele met behulp van de az identity show opdracht.

    export IDENTITY_PRINCIPAL_ID=$(az identity show \
        --name "${USER_ASSIGNED_IDENTITY_NAME}" \
        --resource-group "${RESOURCE_GROUP}" \
        --query principalId \
        --output tsv)
    
  3. Wijs de rol Key Vault Secrets User toe aan de door de gebruiker toegewezen beheerde identiteit met behulp van de opdracht az role assignment create. Deze stap geeft de beheerde identiteit toestemming om geheimen uit de sleutelkluis te lezen.

    az role assignment create \
        --assignee-object-id "${IDENTITY_PRINCIPAL_ID}" \
        --role "Key Vault Secrets User" \
        --scope "${KEYVAULT_RESOURCE_ID}" \
        --assignee-principal-type ServicePrincipal
    
  4. Maak een omgevingsvariabele voor de sleutelkluis-URL met behulp van de az keyvault show opdracht.

    export KEYVAULT_URL="$(az keyvault show \
        --resource-group "${RESOURCE_GROUP}" \
        --name ${KEYVAULT_NAME} \
        --query properties.vaultUri \
        --output tsv)"
    

Voeg de volgende code toe aan main.tf om een geheim te maken in de sleutelkluis.

resource "azurerm_key_vault_secret" "this" {
 name         = local.secret_name
 value        = "Hello from Key Vault"
 key_vault_id = azurerm_key_vault.this.id
}

Een verificatiepod implementeren en toegang testen

  1. Implementeer een pod om te controleren of de workloadidentiteit toegang heeft tot het geheim in de sleutelkluis. In het volgende voorbeeld wordt de afbeelding ghcr.io/azure/azure-workload-identity/msal-go gebruikt, die een voorbeeldtoepassing bevat waarmee een geheim uit Azure Key Vault wordt opgehaald met behulp van Microsoft Entra Workload-id:

    kubectl apply -f - <<EOF
    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
    
  2. Wacht tot de pod de Ready status heeft met behulp van de kubectl wait opdracht.

    kubectl wait --namespace ${SERVICE_ACCOUNT_NAMESPACE} --for=condition=Ready pod/sample-workload-identity-key-vault --timeout=120s
    
  3. Controleer of de SECRET_NAME omgevingsvariabele is ingesteld in de pod met behulp van de kubectl describe opdracht.

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

    Als dit lukt, moet de uitvoer er ongeveer uitzien als in het volgende voorbeeld:

    SECRET_NAME: ${KEYVAULT_SECRET_NAME}
    
  4. Controleer of pods een token kunnen ophalen en toegang hebben tot de resource met behulp van de kubectl logs opdracht.

    kubectl logs sample-workload-identity-key-vault
    

    Als dit lukt, moet de uitvoer er ongeveer uitzien als in het volgende voorbeeld:

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

    Belangrijk

    Azure RBAC-roltoewijzingen kunnen maximaal 10 minuten duren voordat ze zijn doorgegeven. Als de pod geen toegang heeft tot het geheim, moet u mogelijk wachten totdat de roltoewijzing is doorgegeven. Zie Troubleshoot Azure RBAC voor meer informatie.

Microsoft Entra Workload-id uitschakelen op een AKS-cluster

Schakel Microsoft Entra Workload-id uit op het AKS-cluster waarvoor het is ingeschakeld en geconfigureerd. Werk het AKS-cluster bij met behulp van de opdracht az aks update met de parameter --disable-workload-identity.

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

Een pod voor verificatie implementeren

Voeg de volgende code toe main.tf om een verificatiepod te implementeren die de workloadidentiteit gebruikt om toegang te krijgen tot het geheim in de sleutelkluis.

resource "kubernetes_pod" "test" {
 metadata {
   name      = "workload-identity-test"
   namespace = local.service_account_namespace
   labels = {
     "azure.workload.identity/use" = "true"
   }
 }
 spec {
   service_account_name = kubernetes_service_account.this.metadata[0].name
   container {
     name  = "test"
     image = "ghcr.io/azure/azure-workload-identity/msal-go"
     env {
       name  = "KEYVAULT_URL"
       value = azurerm_key_vault.this.vault_uri
     }
     env {
       name  = "SECRET_NAME"
       value = azurerm_key_vault_secret.this.name
     }
   }
 }
}

Terraform initialiseren

Initialiseer Terraform in de map met het main.tf bestand met behulp van de terraform init opdracht. Met deze opdracht wordt de Azure-provider gedownload die is vereist voor het beheren van Azure resources met Terraform.

terraform init

Een Terraform-uitvoeringsplan maken

Maak een Terraform-uitvoeringsplan met behulp van de terraform plan opdracht. Met deze opdracht ziet u de resources die Terraform maakt of wijzigt in uw Azure-abonnement.

terraform plan

De Terraform-configuratie toepassen

Nadat u het uitvoeringsplan hebt bekeken en bevestigd, past u de Terraform-configuratie toe met behulp van de terraform apply opdracht. Met deze opdracht maakt of wijzigt u de resources die zijn gedefinieerd in uw main.tf-bestand in uw Azure-abonnement.

terraform apply

De implementatie controleren

  1. Maak verbinding met uw AKS-cluster met behulp van de az aks get-credentials opdracht.

    az aks get-credentials --name <cluster-name> --resource-group <resource-group>
    
  2. Controleer de status van de verificatiepod met behulp van de kubectl get pods opdracht.

  3. Zodra de pod een Ready status heeft bereikt, controleert u of deze toegang heeft tot het sleutelkluisgeheim door de podlogboeken te controleren met behulp van de kubectl logs opdracht.

    kubectl logs workload-identity-test
    

In dit artikel hebt u een Kubernetes-cluster geïmplementeerd en geconfigureerd om gebruik te maken van Microsoft Entra Workload-id, ter voorbereiding op de authenticatie van toepassingsworkloads met deze referentie. U bent nu klaar om uw toepassing te implementeren en deze te configureren voor het gebruik van de workloadidentiteit met de nieuwste versie van de Azure Identity-clientbibliotheek. Als u uw toepassing niet kunt herschrijven om de nieuwste versie van de clientbibliotheek te gebruiken, kunt u uw toepassingspod instellen voor verificatie met beheeridentiteit met workload-identiteit als kortetermijnoplossing voor migratie.

De integratie Serviceconnector vereenvoudigt de verbindingsconfiguratie voor AKS-workloads en Azure back-upservices. Het verwerkt verificatie- en netwerkconfiguraties veilig en volgt aanbevolen procedures voor het maken van verbinding met Azure-services. Voor meer informatie, zie Connect to Azure OpenAI in Foundry Models in AKS using Microsoft Entra Workload Identity en de Service Connector introduction.