在 Azure Kubernetes 服务 (AKS) 群集中使用 Azure 密钥保管库 提供程序作为 Secrets Store CSI 驱动程序

用于机密存储容器存储接口(CSI)驱动程序的 Azure 密钥保管库 提供程序允许将 Azure 密钥保管库 通过CSI 卷与 Azure Kubernetes 服务(AKS)集群进行集成,作为机密存储。

功能

  • 使用 CSI 卷将机密、密钥和证书装载到 Pod。
  • 支持 CSI 内联卷。
  • 支持将多个机密存储对象装载为单个卷。
  • 支持使用SecretProviderClass 自定义资源定义(CRD)实现 Pod 的可移植性。
  • 支持 Windows 容器。
  • 与 Kubernetes Secrets 同步。
  • 支持自动旋转已挂载内容和已同步的 Kubernetes 密钥。

限制

  • 轮换机密时,将 ConfigMapSecret 作为 subPath 卷装载使用的容器不会收到自动更新,这是 Kubernetes 的限制。 若要使更改生效,应用程序需要通过监视文件系统中的更改或通过重启 Pod 来重新加载更改的文件。 有关详细信息,请参阅机密存储 CSI 驱动程序已知限制
  • 加载项将创建一个在节点资源组(azurekeyvaultsecretsprovider-xxxxx)中命名MC_的托管标识,并自动将其分配给虚拟机规模集。 可使用此托管标识或自己的托管标识访问密钥保管库。 不支持阻止创建身份标识。

先决条件

  • 如果没有 Azure 订阅,可在开始前创建一个试用帐户
  • 检查 Azure CLI 的版本是否为 2.30.0 或更高版本。 如果它是更早的版本,请安装最新版本
  • 如果没有 Azure 订阅,可在开始前创建一个试用帐户

  • 版本 1.6 或更高版本的 Terraform。

  • Azure CLI已安装并登录。安装最新版本

  • 创建 AKS 和密钥保管库资源的权限。

  • 使用以下命令在Azure CLI中设置Azure订阅。 将 <subscriptionId> 替换为订阅 ID。

    az account set --subscription <subscriptionId>
    

网络

角色

  • 本文使用 密钥保管库 机密官员 角色授予帐户在密钥保管库中创建机密的权限。
  • 提供 Azure 密钥保管库 访问权限的文章中,使用的标识需要密钥保管库 证书用户权限来访问对象类型,以及密钥保管库 机密用户权限来访问对象类型

创建 AKS 群集

使用 Azure 密钥保管库 提供程序,为 Secrets Store CSI 驱动程序支持创建 AKS 群集。

  1. 创建命令中用于创建 AKS 群集和 密钥保管库 的变量。

    export RANDOM_STRING=$(printf '%05d%05d' "$RANDOM" "$RANDOM")
    export KEYVAULT_NAME=myKeyVault${RANDOM_STRING}
    export RESOURCE_GROUP=myResourceGroup
    export CLUSTER_NAME=myAKSCluster
    export LOCATION=chinanorth3
    

    Azure 密钥保管库 名称必须全局唯一,字母数字(包括连字符)和 3-24 个字符。 密钥保管库名称将KEYVAULT_NAME 变量的值与myKeyVault 变量的 10 个字符字符串连接在一起。

  2. 使用 az group create 命令创建 Azure 资源组。

    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  3. 使用 az aks create 命令和 --enable-addons azure-keyvault-secrets-provider 参数创建 AKS 群集,该群集具备 Azure 密钥保管库提供程序功能以支持 Secrets Store CSI 驱动程序。

    --enable-addons 参数创建一个用户分配的托管标识, azurekeyvaultsecretsprovider-xxxx 该标识可用于对密钥保管库进行身份验证。 托管标识存储在节点资源组(MC_)中,并自动分配给虚拟机规模集。 可使用此托管标识或自己的托管标识访问密钥保管库。 不支持阻止创建身份标识。

    az aks create \
      --name $CLUSTER_NAME \
      --resource-group $RESOURCE_GROUP \
      --enable-addons azure-keyvault-secrets-provider \
      --generate-ssh-keys
    

    Tip

    如果要使用 Microsoft Entra 工作负荷 ID,该 az aks create 命令必须包含 --enable-oidc-issuer--enable-workload-identity 参数。

创建 AKS 群集

使用以下配置创建 main.tf 文件,以创建具有Azure 密钥保管库提供程序的 AKS 群集,以支持机密存储 CSI 驱动程序。

  1. 创建 Terraform 配置。

    terraform {
     required_version = ">= 1.6.0"
     required_providers {
       azurerm = {
         source  = "hashicorp/azurerm"
         version = "~> 4.0"
       }
     }
    }
    provider "azurerm" {
     features {}
    }
    data "azurerm_client_config" "current" {}
    resource "azurerm_resource_group" "rg" {
     name     = "aks-rg"
     location = "China North3"
    }
    
  2. 创建 AKS 群集。

    resource "azurerm_kubernetes_cluster" "aks" {
     name                = "aks-cluster"
     location            = azurerm_resource_group.rg.location
     resource_group_name = azurerm_resource_group.rg.name
     dns_prefix          = "akscsi"
     default_node_pool {
       name       = "system"
       node_count = 1
       vm_size    = "Standard_DS2_v2"
     }
     identity {
       type = "SystemAssigned"
     }
     key_vault_secrets_provider {
       secret_rotation_enabled = false
     }
    }
    
  3. 部署配置。 形成 Bash 会话,运行以下命令以部署资源:

    terraform init
    terraform validate
    terraform plan
    terraform apply
    

更新现有的 AKS 群集

为支持机密存储 CSI 驱动程序,使用 Azure 密钥保管库 提供程序更新现有的 AKS 群集。

  1. 创建命令中使用的变量。 根据需要替换值以更新现有 AKS 群集或 密钥保管库。

    例如,如果使用的是现有密钥保管库,请替换 KEYVAULT_NAME 变量的值而不使用该 RANDOM_STRING 变量。

    如果没有密钥保管库,Azure 密钥保管库 名称必须全局唯一,字母数字(包括连字符)和 3-24 个字符。 密钥保管库名称将KEYVAULT_NAME 变量的值与myKeyVault 变量的 10 个字符字符串连接在一起。 可以稍后在本文中创建密钥保管库。

    export RANDOM_STRING=$(printf '%05d%05d' "$RANDOM" "$RANDOM")
    export KEYVAULT_NAME=myKeyVault${RANDOM_STRING}
    export RESOURCE_GROUP=myResourceGroup
    export CLUSTER_NAME=myAKSCluster
    export LOCATION=chinanorth3
    
  2. 使用 az aks enable-addons 命令更新现有的 AKS 群集以启用 Secrets Store CSI 驱动程序的 Azure 密钥保管库 提供程序功能,并启用 azure-keyvault-secrets-provider 加载项。 加载项会创建用户分配的托管标识,你可以使用该标识向密钥保管库进行身份验证。

    az aks enable-addons \
      --addons azure-keyvault-secrets-provider \
      --name $CLUSTER_NAME \
      --resource-group $RESOURCE_GROUP
    

    启用 Azure 密钥保管库 机密提供程序后,AKS 会创建一个托管 azurekeyvaultsecretsprovider-xxxx 标识,该标识可用于向密钥保管库进行身份验证。 托管标识存储在节点资源组(MC_)中,并自动分配给虚拟机规模集。 可使用此托管标识或自己的托管标识访问密钥保管库。 不支持阻止创建身份标识。

更新现有的 AKS 群集

使用以下配置创建 main.tf 文件,以使用 Azure 密钥保管库提供程序更新现有 AKS 群集以支持机密存储 CSI 驱动程序。

  1. 更新现有的 AKS 群集。

    resource "azurerm_kubernetes_cluster" "aks" {
     name                = "<existing-cluster>"
     resource_group_name = "<resource-group>"
     key_vault_secrets_provider {
       secret_rotation_enabled = false
     }
    }
    
  2. 部署配置。 形成 Bash 会话,运行以下命令来部署配置:

    Run the following commands to apply the updates:
    
    terraform init
    terraform validate
    terraform plan
    terraform apply
    

验证托管标识和密钥保管库提供程序安装

如果使用 Terraform 创建新群集或更新现有群集,则需要将变量替换为在 Terraform 配置中使用的值,如 $CLUSTER_NAME 以下命令中所示。

验证托管标识

使用以下步骤验证是否已创建托管标识并将其分配给集群的虚拟机规模集。

  1. 使用 az aks show 命令验证是否已创建并分配给群集的托管标识。

    az aks show \
      --name $CLUSTER_NAME \
      --resource-group $RESOURCE_GROUP \
      --query addonProfiles
    
    {
      "azureKeyvaultSecretsProvider": {
        "config": {
          "enableSecretRotation": "false",
          "rotationPollInterval": "2m"
        },
        "enabled": true,
        "identity": {
          "clientId": "00001111-aaaa-2222-bbbb-3333cccc4444",
          "objectId": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
          "resourceId": "/subscriptions/<subscriptionID>/resourcegroups/MC_myResourceGroup_myAKSCluster_eastus2/providers/Microsoft.ManagedIdentity/userAssignedIdentities/azurekeyvaultsecretsprovider-myakscluster"
        }
      }
    }
    

    resourceId 属性显示资源组和标识的名称 azurekeyvaultsecretsprovider-myakscluster

  2. 验证是否已将托管标识分配给节点资源组的虚拟机规模集。

    NODE_RG=$(az aks show \
      --name $CLUSTER_NAME \
      --resource-group $RESOURCE_GROUP \
      --query nodeResourceGroup --output tsv)
    
    VMSS_NAME=$(az vmss list \
      --resource-group $NODE_RG \
      --query [].name --output tsv)
    
    az vmss show --name $VMSS_NAME --resource-group $NODE_RG --query '[id, identity]'
    

    输出显示了虚拟机规模集 Microsoft.Compute/virtualMachineScaleSets 的资源 ID,以及 userAssignedIdentities 属性中包含用于确认该标识分配至虚拟机规模集的资源 ID azurekeyvaultsecretsprovider-myakscluster

验证适用于机密存储 CSI 驱动程序的 Azure 密钥保管库 提供程序安装

  1. 使用 az aks get-credentials 命令获取 AKS 群集凭据。

    az aks get-credentials \
      --name $CLUSTER_NAME \
      --resource-group $RESOURCE_GROUP
    
  2. 使用kubectl get pods命令验证安装是否完成,该命令会列出命名空间secrets-store-csi-driver中具有secrets-store-provider-azurekube-system标签的所有 Pods。

    kubectl get pods -n kube-system -l 'app in (secrets-store-csi-driver,secrets-store-provider-azure)' -o wide
    

    o wide 标志会在输出中包括每个 Pod 运行的节点。

    输出应类似于以下示例输出:

    NAME                                     READY   STATUS    RESTARTS   AGE    NODE
    aks-secrets-store-csi-driver-4vpkj       3/3     Running   2          4m25s  aks-nodepool1-12345678-vmss000002
    aks-secrets-store-csi-driver-ctjq6       3/3     Running   2          4m21s  aks-nodepool1-12345678-vmss000001
    aks-secrets-store-csi-driver-tlvlq       3/3     Running   2          4m24s  aks-nodepool1-12345678-vmss000000
    aks-secrets-store-provider-azure-5p4nb   1/1     Running   0          4m21s  aks-nodepool1-12345678-vmss000000
    aks-secrets-store-provider-azure-6pqmv   1/1     Running   0          4m24s  aks-nodepool1-12345678-vmss000001
    aks-secrets-store-provider-azure-f5qlm   1/1     Running   0          4m25s  aks-nodepool1-12345678-vmss000002
    

创建新的密钥保管库

az keyvault create运行该命令,创建启用了 Azure RBAC 的新密钥保管库。

az keyvault create \
  --name $KEYVAULT_NAME \
  --resource-group $RESOURCE_GROUP \
  --location $LOCATION \
  --enable-rbac-authorization

创建新的密钥保管库时,即使不包含 --enable-rbac-authorization 该参数,Azure RBAC 也默认启用。

有关 密钥保管库 权限模型和 Azure RBAC 的详细信息,请参阅使用 Azure 基于角色的访问控制对 密钥保管库 密钥、证书和保密信息的访问

更新现有密钥保管库

运行 az keyvault update 命令来使用 Azure 基于角色的访问控制(Azure RBAC)更新现有的密钥保管库。 更新已禁用 Azure RBAC 的现有密钥保管库时,需要使用 --enable-rbac-authorization 参数来启用 Azure RBAC。

az keyvault update \
  --name $KEYVAULT_NAME \
  --resource-group $RESOURCE_GROUP \
  --enable-rbac-authorization

有关 密钥保管库 权限模型和 Azure RBAC 的详细信息,请参阅 使用 Azure 基于角色的访问控制提供对 密钥保管库 密钥、证书和机密的访问权限

将角色分配和机密添加到密钥保管库

  1. az keyvault show运行以下命令来验证密钥保管库是否已启用 Azure RBAC。

    az keyvault show \
      --name $KEYVAULT_NAME \
      --resource-group $RESOURCE_GROUP \
      --query properties.enableRbacAuthorization
    

    输出应为 true.

  2. 使用 az role assignment create 命令将用户帐户的角色分配添加到密钥保管库范围,以便在下一步中添加密钥保管库机密。

    添加了具有唯一标识符b86a8fe4-44ce-4948-aee5-eccb2c155cd7角色,可以使用名称或唯一标识符。 使用角色的唯一标识符是防止角色名称更改时出现问题的最佳做法。

    KEYVAULT_ID=$(az keyvault show \
      --name $KEYVAULT_NAME \
      --resource-group $RESOURCE_GROUP \
      --query id -o tsv)
    
    MYID=$(az ad signed-in-user show --query id --output tsv)
    
    az role assignment create \
      --assignee-object-id $MYID \
      --role "b86a8fe4-44ce-4948-aee5-eccb2c155cd7" \
      --scope $KEYVAULT_ID \
      --assignee-principal-type User
    

    角色分配可能需要几分钟才能生效。 可以使用以下命令验证角色分配是否已创建:

    az role assignment list \
      --assignee-object-id $MYID \
      --scope $KEYVAULT_ID \
      --query '[].{Role:roleDefinitionName, Scope:scope}' \
      --output table
    
  3. 使用ExampleSecret命令在密钥保管库中创建一个纯az keyvault secret set文本机密。

    密钥保管库可以存储密钥、机密和证书。 该 value 参数使用 RANDOM_STRING 变量为机密创建唯一值。

    az keyvault secret set \
      --vault-name $KEYVAULT_NAME \
      --name ExampleSecret \
      --value MyAKSExampleSecret${RANDOM_STRING}
    
  4. 使用 az keyvault secret show 命令验证是否已将机密添加到密钥保管库。

    az keyvault secret show --vault-name $KEYVAULT_NAME --name ExampleSecret
    

创建新的密钥保管库

更新 main.tf 文件,以创建启用了Azure基于角色的访问控制(Azure RBAC)的新密钥保管库。

  1. 创建启用了 Azure RBAC 的新密钥保管库。

    data "azurerm_client_config" "current" {}
    resource "random_string" "suffix" {
     length  = 5
     special = false
     upper   = false
    }
    resource "azurerm_key_vault" "kv" {
     name                = "akskv${random_string.suffix.result}"
     location            = azurerm_resource_group.rg.location
     resource_group_name = azurerm_resource_group.rg.name
     tenant_id           = data.azurerm_client_config.current.tenant_id
     sku_name            = "standard"
     enable_rbac_authorization = true
    }
    
  2. 分配密钥保管库机密管理员角色。

    resource "azurerm_role_assignment" "kv_role" {
     scope                = azurerm_key_vault.kv.id
     role_definition_name = "Key Vault Secrets Officer"
     principal_id         = data.azurerm_client_config.current.object_id
    }
    
  3. 在密钥保管库中创建 ExampleSecret。

    resource "azurerm_key_vault_secret" "example" {
     name         = "ExampleSecret"
     value        = "MyAKSExampleSecret"
     key_vault_id = azurerm_key_vault.kv.id
    }
    
  4. 部署配置。 形成 Bash 会话,运行以下命令以部署更新的配置:

    terraform plan
    terraform apply
    
  5. 使用 az keyvault secret show 命令验证 ExampleSecret 是否已添加到密钥保管库。 请将 <keyvault-name> 替换为您在 Terraform 配置中创建的密钥保管库的名称。

    az keyvault secret show \
     --vault-name <keyvault-name> \
     --name ExampleSecret
    

更新现有密钥保管库

更新 main.tf 文件,以使用已启用Azure基于角色的访问控制(Azure RBAC)更新现有密钥保管库。

  1. 更新现有密钥保管库以启用 Azure RBAC。

    resource "azurerm_key_vault" "kv" {
     name                = "<existing-kv>"
     resource_group_name = "<resource-group>"
     enable_rbac_authorization = true
    }
    
  2. 分配角色并添加机密。

    resource "azurerm_role_assignment" "kv_role" {
     scope                = azurerm_key_vault.kv.id
     role_definition_name = "Key Vault Secrets Officer"
     principal_id         = data.azurerm_client_config.current.object_id
    }
    resource "azurerm_key_vault_secret" "example" {
     name         = "ExampleSecret"
     value        = "MyAKSExampleSecret"
     key_vault_id = azurerm_key_vault.kv.id
    }
    
  3. 部署配置。 形成 Bash 会话,运行以下命令以部署更新的配置:

    terraform plan
    terraform apply
    

清理资源

如果要转到下一篇文章并需要这些资源,请忽略以下步骤。 否则,如果已完成并且不打算继续阅读下一篇文章,则应删除本文中创建的资源,以避免不必要的成本。

  1. 从本地 .kube/config 文件中删除集群凭据。

    KUBE_CONTEXT=$(kubectl config current-context)
    kubectl config delete-context $KUBE_CONTEXT
    
  2. 使用命令删除资源组及其中的所有资源,包括节点资源组 (MC_az group delete 中的资源。

    az group delete --name $RESOURCE_GROUP --yes --no-wait
    

terraform destroy 命令删除当前 Terraform 配置和状态文件中定义的所有资源。 仅从本文使用的工作目录中运行此命令。

Warning

如果使用的是现有资源或生产资源,请在运行之前仔细查看执行计划:

terraform plan -destroy

避免针对共享或导入的基础结构运行 terraform destroy ,除非确定可以安全删除。 有关详细信息,请参阅 Terraform 文档中关于 [terraform destroy][terraform destroy] 命令的说明。

  1. 从本地 .kube/config 文件中删除集群凭据。

    KUBE_CONTEXT=$(kubectl config current-context)
    kubectl config delete-context $KUBE_CONTEXT
    
  2. 运行以下命令以删除本文中创建的资源:

    terraform destroy
    

后续步骤

本文介绍了如何将适用于机密存储 CSI 驱动程序的 Azure 密钥保管库 提供程序用于 AKS 群集。 现在需要提供一个标识来访问 Azure 密钥保管库。 若要了解如何操作,请继续阅读下一篇文章。