在 Azure Kubernetes Service (AKS) 叢集中使用適用於祕密存放區 CSI 驅動程式的 Azure Key Vault 提供者

適用於密碼存放區容器儲存體介面 (CSI) 驅動程式的 Azure Key Vault 提供者可讓您透過 CSI 磁碟區,將 Azure Key Vault 與 Azure Kubernetes Service (AKS) 叢集整合為密碼存放區。

特性

  • 使用 CSI 磁碟區,將祕密、金鑰和憑證掛接到 Pod。
  • 支援 CSI 內嵌磁碟區。
  • 支援將多個祕密存放區物件掛接為單一磁碟區。
  • 透過SecretProviderClass自訂資源定義 (CRD) 支援 Pod 可攜性。
  • 支援 Windows 容器。
  • 與 Kubernetes 祕密同步。
  • 支援自動輪替掛接的內容和同步的 Kubernetes 祕密。

限制

  • 使用 ConfigMapSecret 作為 subPath 磁碟區掛接的容器不會在密碼變換時接收自動更新,這是 Kubernetes 限制。 若要讓變更生效,應用程式必須藉由監看檔案系統中的變更或重新啟動Pod來重載變更的檔案。 如需詳細資訊,請參閱祕密存放區 CSI 驅動程式的已知限制 (英文)。
  • 外掛會在節點資源群組azurekeyvaultsecretsprovider-xxxxx中建立一個名為MC_的託管身份,並自動指派到虛擬機器規模設定集。 您可以使用此受控識別或自己的受控識別來存取金鑰保存庫。 不支援防止建立身分識別。

先決條件

  • 如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶
  • 請確定您的 Azure CLI 版本是 2.30.0 或更新版本。 如果是較早的版本,請安裝最新版本
  • 如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶

  • Terraform 是 1.6 或更新版本。

  • Azure CLI 已安裝並登入。安裝最新版本

  • 建立 AKS 和 金鑰保存庫 資源的權限。

  • 請用以下指令在 Azure CLI 中設定你的 Azure 訂閱。 使用您的訂用帳戶 ID 來取代 <subscriptionId>

    az account set --subscription <subscriptionId>
    

網路

角色

建立 AKS 叢集

建立一個 AKS 叢集,並使用 Azure Key Vault 提供者支援「Secrets Store CSI Driver」。

  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=eastus2
    

    Azure Key Vault 名稱必須是全域唯一、包含連字號的字母數字,且字元長度為 3 至 24 個字元。 金鑰庫名稱將 KEYVAULT_NAME 變數 myKeyVault 的值 RANDOM_STRING 與變數的 10 字元字串串接起來。

  2. 使用 az group create 命令來建立 Azure 資源群組。

    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  3. 使用 az aks create (部分機器翻譯) 命令搭配 --enable-addons azure-keyvault-secrets-provider 參數,利用適用於祕密存放區 CSI 驅動程式的 Azure Key Vault 提供者功能來建立 AKS 叢集。

    這個 --enable-addons 參數會建立一個由使用者指派的受控身分識別,名為 azurekeyvaultsecretsprovider-xxxx,你可以用來驗證你的金鑰保存庫。 管理身份會儲存在節點資源群組(MC_)中,並自動分配到虛擬機規模集。 您可以使用此受控識別或自己的受控識別來存取金鑰保存庫。 不支援防止建立身分識別。

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

    小提示

    如果你想使用 Microsoft Entra 工作負載 ID, az aks create 指令必須包含 --enable-oidc-issuer and --enable-workload-identity 參數。

建立 AKS 叢集

建立一個 main.tf 檔案,並採用以下設定,以 Azure Key Vault 作為 Secrets Store CSI 驅動程式支援的供應者來建立一個 AKS 叢集。

  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 = "East US"
    }
    
  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 叢集

用 Azure Key Vault provider 更新現有 AKS 叢集,以支援 Secrets Store CSI Driver 。

  1. 建立用於指令的變數。 根據需要替換這些值,以更新你現有的 AKS 叢集或 金鑰保存庫。

    舉例來說,如果你正在使用現有的金鑰保險庫,就替換 KEYVAULT_NAME 變數的值,但不使用該 RANDOM_STRING 變數。

    如果你沒有金鑰保險庫,Azure 金鑰庫名稱必須是全域唯一、包含連字號的字母數字,且 3 到 24 個字元。 金鑰庫名稱將 KEYVAULT_NAME 變數 myKeyVault 的值 RANDOM_STRING 與變數的 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=eastus2
    
  2. az aks enable-addons命令更新現有的 AKS 叢集,啟用 Azure Key Vault 提供者以支持 Secrets Store CSI Driver 功能,並啟用azure-keyvault-secrets-provider附加元件。 此附加元件會建立使用者指派的受控識別,以供您用來向金鑰保存庫進行驗證。

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

    啟用 Azure Key Vault 秘密提供者後,AKS 會建立一個名為 azurekeyvaultsecretsprovider-xxxx Managed Identity 的身份,讓你用來驗證你的 Key Vault 身份。 管理身份會儲存在節點資源群組(MC_)中,並自動分配到虛擬機規模集。 您可以使用此受控識別或自己的受控識別來存取金鑰保存庫。 不支援防止建立身分識別。

更新現有的 AKS 叢集

建立一個 main.tf 檔案,並採用以下設定,以更新現有的 AKS 叢集,以 Azure Key Vault 提供 Secrets Store 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 建立新叢集或更新現有叢集,你需要像以下指令那樣替換變數 $CLUSTER_NAME ,換成你在 Terraform 設定中使用的值。

驗證管理身份

使用下列步驟確認已建立受控身分識別,並指派給叢集的虛擬機器擴展集。

  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 屬性 (具有 azurekeyvaultsecretsprovider-myakscluster 的資源 ID),確認身分識別已指派給虛擬機器擴展集。

驗證適用於祕密存放區 CSI 驅動程式的 Azure Key Vault 提供者安裝

  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 標籤的 pod。

    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) 更新現有的金鑰保險庫。 --enable-rbac-authorization 參數是啟用 Azure RBAC 的必要條件,當你更新已停用 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] 指令驗證秘密是否被加入金鑰庫。

    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. 驗證 ExampleSecret 是透過 [az keyvault secret show][az-keyvault-secret-show] 指令加入金鑰庫的。 將 <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 destroy 指令的 Terraform 文件。

  1. 從本地的 .kube/config 檔案中移除叢集的憑證。

    KUBE_CONTEXT=$(kubectl config current-context)
    kubectl config delete-context $KUBE_CONTEXT
    
  2. 執行以下指令以移除本文中建立的資源:

    terraform destroy
    

後續步驟

在本文中,您已了解如何在 AKS 叢集中使用適用於祕密存放區 CSI 驅動程式的 Azure Key Vault 提供者。 您現在需要提供身分識別來存取 Azure Key Vault。 若要深入了解,請繼續進行下一篇文章。