Distribuera och konfigurera Microsoft Entra Workload ID i ett Azure Kubernetes Service (AKS) kluster

I den här artikeln får du lära dig hur du distribuerar och konfigurerar ett Azure Kubernetes Service (AKS) kluster med Microsoft Entra Workload ID. Stegen i den här artikeln omfattar:

  • Skapa ett nytt eller uppdatera ett befintligt AKS-kluster med hjälp av Azure CLI eller Terraform med OpenID Connect-utfärdare (OIDC) och Microsoft Entra Workload ID aktiverat.
  • Skapa en arbetsbelastningsidentitet och ett Kubernetes-tjänstkonto.
  • Konfigurera den hanterade identiteten för tokenfederation.
  • Distribuera arbetsbelastningen och verifiera autentiseringen med arbetsbelastningsidentiteten.
  • Du kan även ge en podd i klustret åtkomst till hemligheter från ett Azure Key Vault.

Förutsättningar

  • Om du inte har ett Azure konto skapar du ett fritt konto innan du börjar.
  • Den här artikeln kräver version 2.47.0 eller senare av Azure CLI. Om du använder Azure Cloud Shell är den senaste versionen redan installerad. Kör az --version för att hitta versionen. Om du behöver installera eller uppgradera kan du läsa Installera Azure CLI.
  • Kontrollera att den identitet som du använder för att skapa klustret har lämpliga minimibehörigheter. Mer information finns i Access och identitetsalternativ för Azure Kubernetes Service (AKS).
  • Om du har flera Azure prenumerationer väljer du lämpligt prenumerations-ID där resurserna ska faktureras med hjälp av kommandot az account set.

Kommentar

Du kan använda Service Connector för att konfigurera vissa steg automatiskt. Mer information finns i Tutorial: Anslut till Azure lagringskonto i Azure Kubernetes Service (AKS) med Service Connector med Microsoft Entra Workload ID.

Skapa Terraform-konfigurationsfilen

Terraform-konfigurationsfiler definierar infrastrukturen som Terraform skapar och hanterar.

  1. Skapa en fil med namnet main.tf och lägg till följande kod för att definiera Terraform-versionen och ange Azure provider:

    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. Lägg till följande kod för main.tf att definiera återanvändbara variabler och generera unika namn för alla resurser:

    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}"
    }
    

Skapa en resursgrupp

Skapa en resursgrupp med kommandot az group create.

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}"

Lägg till följande kod i main.tf för att skapa en Azure resursgrupp. Uppdatera värdet location så att det matchar önskad Azure region.

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

Aktivera OIDC-utfärdare och Microsoft Entra Workload ID i ett AKS-kluster

Du kan aktivera OIDC-utfärdare och Microsoft Entra Workload ID på ett nytt eller befintligt AKS-kluster.

Skapa ett AKS-kluster med kommandot az aks create med parametern --enable-oidc-issuer för att aktivera OIDC-utfärdaren och parametern --enable-workload-identity för att aktivera Microsoft Entra Workload ID. I följande exempel skapas ett kluster med en enda nod:

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

Efter några minuter slutförs kommandot och returnerar JSON-formaterad information om klustret.

Lägg till följande kod i main.tf för att skapa ett AKS-kluster med OIDC-utfärdare och Microsoft Entra Workload ID aktiverat:

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"
 }
}

Hämta URL:en för OIDC-utfärdaren

Hämta url:en för OIDC-utfärdaren az aks show med kommandot och spara den i en miljövariabel.

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

Miljövariabeln bör innehålla utfärdarens URL, ungefär som i följande exempel:

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

Som standard är utfärdaren inställd på att använda bas-URL:en https://{region}.oic.prod-aks.azure.com/{tenant_id}/{uuid}, där värdet för {region} matchar platsen där AKS-klustret distribueras. Värdet {uuid} representerar OIDC-nyckeln, som är ett slumpmässigt genererat och oföränderligt GUID för varje kluster.

Lägg till följande kod i main.tf för att hämta OIDC-utfärdarens URL:

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

Skapa en hanterad identitet

  1. Hämta ditt prenumerations-ID och spara det i en miljövariabel med hjälp av az account show kommandot .

    export SUBSCRIPTION="$(az account show --query id --output tsv)"
    
  2. Skapa en användartilldelad hanterad identitet med kommandot az identity create .

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

    I följande utdataexempel visas hur en hanterad identitet har skapats:

    {
      "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. Hämta klient-ID för den hanterade identiteten och spara det i en miljövariabel med kommandot az identity show .

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

Lägg till följande kod i main.tf för att skapa en hanterad identitet:

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
}

Skapa ett Kubernetes-tjänstkonto

  1. Anslut till ditt AKS-kluster med hjälp av az aks get-credentials kommandot .

    az aks get-credentials --name "${CLUSTER_NAME}" --resource-group "${RESOURCE_GROUP}"
    
  2. Skapa ett Kubernetes-tjänstkonto och kommentera det med klient-ID:t för den hanterade identiteten genom att använda följande manifest med kommandot kubectl apply .

    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
    

    Följande utdata visar hur arbetsbelastningsidentiteten har skapats:

    serviceaccount/workload-identity-sa created
    
  1. Lägg till följande kod för att main.tf konfigurera Kubernetes-åtkomst så att Kubernetes-resurser kan skapas:

    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. Lägg till följande kod för att main.tf skapa ett Kubernetes-tjänstkonto och kommentera det med klient-ID:t för den hanterade identiteten:

    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
       }
     }
    }
    

Skapa federerade identitetsautentiseringsuppgifter

Skapa en federerad identitetsautentiseringsuppgift mellan den hanterade identiteten, utfärdaren av tjänstkontot och ämnet med kommandot az identity federated-credential create .

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

Kommentar

Det tar några sekunder innan den federerade identitetsautentiseringsuppgiften sprids efter att den har lagts till. Om en tokenbegäran görs omedelbart efter att den federerade identitetsautentiseringsuppgiften har lagts till kan begäran misslyckas tills cachen har uppdaterats. För att undvika det här problemet kan du lägga till en liten fördröjning när du har lagt till den federerade identitetsautentiseringsuppgiften.

Lägg till följande kod till main.tf för att skapa en federerad identitetssignal mellan den hanterade identiteten, utfärdaren av tjänstkontot och ämnet:

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"]
}

Mer information om federerade identitetsautentiseringsuppgifter i Microsoft Entra finns i Översikt över federerade identitetsautentiseringsuppgifter i Microsoft Entra ID.

Skapa ett nyckelvalv med Azure RBAC-auktorisering

I följande exempel visas hur du använder behörighetsmodellen Azure rollbaserad åtkomstkontroll (Azure RBAC) för att ge podden åtkomst till nyckelvalvet. Mer information om Azure RBAC-behörighetsmodellen för Azure Key Vault finns i Bevilja behörighet till program för att få åtkomst till ett Azure-nyckelvalv med hjälp av Azure RBAC.

  1. Skapa ett nyckelvalv med rensningsskydd och Azure RBAC-auktorisering aktiverat med kommandot az keyvault create. Du kan också använda ett befintligt nyckelvalv om det har konfigurerats för både rensningsskydd och Azure RBAC-auktorisering.

    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. Hämta resurs-ID:t för nyckelvalvet och spara det i en miljövariabel med hjälp av az keyvault show kommandot .

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

Lägg till följande kod i main.tf för att skapa ett nyckelvalv med Azure RBAC-auktorisering:

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
}

Tilldela RBAC-behörigheter för hantering av nyckelvalv

  1. Hämta anroparens objekt-ID och spara det i en miljövariabel med hjälp av az ad signed-in-user show kommandot .

    export CALLER_OBJECT_ID=$(az ad signed-in-user show --query id -o tsv)
    
  2. Tilldela dig rollen Azure RBAC Key Vault Secrets Officer så att du kan lägga till en hemlighet i det nya nyckelvalvet genom att använda kommandot az role assignment create.

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

Lägg till följande kod i main.tf för att tilldela dig själv rollen Azure RBAC Key Vault Secrets Officer så att du kan skapa en hemlighet i den nya key vault och tilldela rollen Key Vault Secrets User till den användartilldelade hanterade identiteten:

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
}

Skapa och konfigurera hemlig åtkomst

  1. Skapa en hemlighet i nyckelvalvet med kommandot az keyvault secret set .

    export KEYVAULT_SECRET_NAME="my-secret$RANDOM_ID"
    az keyvault secret set \
        --vault-name "${KEYVAULT_NAME}" \
        --name "${KEYVAULT_SECRET_NAME}" \
        --value "Hello\!"
    
  2. Hämta huvud-ID:t för den användartilldelade hanterade identiteten och spara den i en miljövariabel med kommandot az identity show .

    export IDENTITY_PRINCIPAL_ID=$(az identity show \
        --name "${USER_ASSIGNED_IDENTITY_NAME}" \
        --resource-group "${RESOURCE_GROUP}" \
        --query principalId \
        --output tsv)
    
  3. Tilldela rollen Key Vault Secrets User till den användartilldelade hanterade identiteten med hjälp av kommandot az role assignment create. Det här steget ger den hanterade identiteten behörighet att läsa sekretessuppgifter från Key Vault.

    az role assignment create \
        --assignee-object-id "${IDENTITY_PRINCIPAL_ID}" \
        --role "Key Vault Secrets User" \
        --scope "${KEYVAULT_RESOURCE_ID}" \
        --assignee-principal-type ServicePrincipal
    
  4. Skapa en miljövariabel för nyckelvalvs-URL:en med hjälp av az keyvault show kommandot .

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

Lägg till följande kod i main.tf för att skapa ett sekretess i nyckelvalvet:

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

Distribuera en verifieringspodd och testa åtkomst

  1. Distribuera en pod för att verifiera att arbetsbelastnings identitet kan komma åt hemligheten i nyckelvalvet. I följande exempel används avbildningen ghcr.io/azure/azure-workload-identity/msal-go, som innehåller ett exempelprogram som hämtar en hemlighet från Azure Key Vault med hjälp av 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. Vänta tills podden är i Ready tillståndet med kommandot kubectl wait .

    kubectl wait --namespace ${SERVICE_ACCOUNT_NAMESPACE} --for=condition=Ready pod/sample-workload-identity-key-vault --timeout=120s
    
  3. Kontrollera att SECRET_NAME miljövariabeln har angetts i podden med hjälp av kubectl describe kommandot .

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

    Om det lyckas bör utdata likna följande exempel:

    SECRET_NAME: ${KEYVAULT_SECRET_NAME}
    
  4. Kontrollera att poddar kan hämta en token och komma åt resursen med hjälp av kubectl logs kommandot .

    kubectl logs sample-workload-identity-key-vault
    

    Om det lyckas bör utdata likna följande exempel:

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

    Viktigt!

    Azure RBAC-rolltilldelningar kan ta upp till 10 minuter att propagera. Om podden inte kan komma åt hemligheten kan du behöva vänta tills rolltilldelningen sprids. Mer information finns i Troubleshoot Azure RBAC.

Inaktivera Microsoft Entra Workload ID i ett AKS-kluster

Inaktivera Microsoft Entra Workload ID i AKS-klustret där det har aktiverats och konfigurerats, uppdatera AKS-klustret med hjälp av kommandot az aks update med parametern --disable-workload-identity.

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

Distribuera en verifieringspod

Lägg till följande kod i main.tf för att distribuera en verifieringspodd som använder arbetsbelastningsidentiteten för att komma åt hemligheten i nyckelvalvet.

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
     }
   }
 }
}

Initiera Terraform

Initiera Terraform i katalogen som innehåller main.tf filen med hjälp av terraform init kommandot . Det här kommandot laddar ned den Azure provider som krävs för att hantera Azure resurser med Terraform.

terraform init

Skapa en Terraform-utförandeplan

Skapa en Terraform-körningsplan med kommandot terraform plan . Det här kommandot visar de resurser som Terraform skapar eller ändrar i din Azure-prenumeration.

terraform plan

Applicera Terraform-konfigurationen

När du har granskat och bekräftat körningsplanen, verkställer du Terraform-konfigurationen med kommandot terraform apply. Det här kommandot skapar eller ändrar de resurser som definierats i filen main.tf i din Azure-prenumeration.

terraform apply

Verifiera driftsättningen

  1. Anslut till ditt AKS-kluster med hjälp av az aks get-credentials kommandot .

    az aks get-credentials --name <cluster-name> --resource-group <resource-group>
    
  2. Kontrollera statusen för verifieringspodden med hjälp av kubectl get pods kommandot .

  3. När podden når ett Ready tillstånd kontrollerar du att den kan komma åt nyckelvalvets hemlighet genom att kontrollera poddloggarna med kommandot kubectl logs .

    kubectl logs workload-identity-test
    

I den här artikeln distribuerade du ett Kubernetes-kluster och konfigurerade det att använda Microsoft Entra Workload ID för att förbereda programarbetsbelastningar för att autentisera med den identiteten. Nu är du redo att distribuera ditt program och konfigurera det så att det använder arbetsbelastningsidentiteten med den senaste versionen av Azure Identity klientbiblioteket. Om du inte kan skriva om programmet för att använda den senaste klientbiblioteksversionen kan du konfigurera programpodden för att autentisera med hanterad identitet med workload identity som en kortsiktig migreringslösning.

Integreringen Service förenklar anslutningskonfigurationen för AKS-arbetsbelastningar och Azure säkerhetskopieringstjänster. Den hanterar autentisering och nätverkskonfigurationer på ett säkert sätt och följer metodtipsen för att ansluta till Azure tjänster. Mer information finns i Connect to Azure OpenAI in Foundry Models in AKS using Microsoft Entra Workload Identity och i Service Connector-introduktionen.