將 Azure 身分識別提供者 連線 至 Azure Kubernetes Service 中的 Azure 金鑰保存庫 秘密存放區 CSI 驅動程式 (AKS)
Azure Kubernetes Service 上的秘密存放區容器 儲存體 介面 (CSI) 驅動程式 (AKS) 提供各種識別型存取 Azure 金鑰保存庫 的方法。 本文概述使用角色型訪問控制 (RBAC) 或 OpenID 連線 (OIDC) 安全性模型來存取金鑰保存庫和 AKS 叢集的時機這些方法和最佳做法。
您可以使用下列其中一個存取方法:
CSI 驅動程式的必要條件
- 開始之前,請確定您完成在 AKS 叢集中使用 Azure 金鑰保存庫 提供者將 CSI 驅動程式儲存在 Azure Kubernetes Service (AKS) 叢集中的步驟,以啟用 Azure 金鑰保存庫 秘密存放區 CSI 驅動程式。
使用 Microsoft Entra 工作負載 ID 存取
Microsoft Entra 工作負載 ID 是 Pod 上執行的應用程式用來向其他 Azure 服務進行驗證的身分識別,例如軟體中的工作負載。 秘密存放區 CSI 驅動程式會與原生 Kubernetes 功能整合,以與外部識別提供者同盟。
在此安全性模型中,AKS 叢集會作為令牌簽發者。 然後,Microsoft Entra 識別符會使用 OIDC 來探索公開簽署密鑰,並在交換服務帳戶令牌之前驗證服務帳戶令牌的真實性。 若要讓工作負載交換投影到其磁碟區的服務帳戶令牌以取得 Microsoft Entra 令牌,您需要 Azure SDK 中的 Azure 身分識別客戶端連結庫或 Microsoft 驗證連結庫 (MSAL)
注意
- 此驗證方法會取代 Microsoft Entra Pod 受控識別(預覽)。 自 2022 年 10 月 24 日起,Azure Kubernetes Service 中的 開放原始碼 Microsoft Entra Pod 受控識別 (預覽版) 已被取代。
- Microsoft Entra 工作負載 ID 同時支援 Windows 和 Linux 叢集。
設定工作負載身分識別
使用 命令設定您的訂用
az account set
帳戶。export SUBSCRIPTION_ID=<subscription id> export RESOURCE_GROUP=<resource group name> export UAMI=<name for user assigned identity> export KEYVAULT_NAME=<existing keyvault name> export CLUSTER_NAME=<aks cluster name> az account set --subscription $SUBSCRIPTION_ID
使用
az identity create
命令建立受控識別。az identity create --name $UAMI --resource-group $RESOURCE_GROUP export USER_ASSIGNED_CLIENT_ID="$(az identity show -g $RESOURCE_GROUP --name $UAMI --query 'clientId' -o tsv)" export IDENTITY_TENANT=$(az aks show --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --query identity.tenantId -o tsv)
建立角色指派,以授與工作負載身分識別許可權,以使用
az role assignment create
命令存取密鑰保存庫秘密、存取密鑰和憑證。export KEYVAULT_SCOPE=$(az keyvault show --name $KEYVAULT_NAME --query id -o tsv) az role assignment create --role "Key Vault Administrator" --assignee $USER_ASSIGNED_CLIENT_ID --scope $KEYVAULT_SCOPE
使用
az aks show
命令取得 AKS 叢集 OIDC 簽發者 URL。注意
此步驟假設您有已啟用 OIDC 簽發者 URL 的現有 AKS 叢集。 如果您尚未啟用它,請參閱 使用 OIDC 簽發者 更新 AKS 叢集以啟用它。
export AKS_OIDC_ISSUER="$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "oidcIssuerProfile.issuerUrl" -o tsv)" echo $AKS_OIDC_ISSUER
在 Microsoft Entra 應用程式、服務帳戶簽發者和主體之間建立同盟身分識別認證。 使用下列命令取得 Microsoft Entra 應用程式的物件識別碼。 請務必使用 Kubernetes 服務帳戶名稱和其命名空間來更新 和
serviceAccountNamespace
的值serviceAccountName
。export SERVICE_ACCOUNT_NAME="workload-identity-sa" # sample name; can be changed export SERVICE_ACCOUNT_NAMESPACE="default" # can be changed to namespace of your workload 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
使用
az identity federated-credential create
命令,在受控識別、服務帳戶簽發者和主體之間建立同盟身分識別認證。export FEDERATED_IDENTITY_NAME="aksfederatedidentity" # can be changed as needed az identity federated-credential create --name $FEDERATED_IDENTITY_NAME --identity-name $UAMI --resource-group $RESOURCE_GROUP --issuer ${AKS_OIDC_ISSUER} --subject system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}
SecretProviderClass
使用kubectl apply
命令與下列 YAML 指令稿部署 。cat <<EOF | kubectl apply -f - # This is a SecretProviderClass example using workload identity to access your key vault apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: azure-kvname-wi # needs to be unique per namespace spec: provider: azure parameters: usePodIdentity: "false" clientID: "${USER_ASSIGNED_CLIENT_ID}" # Setting this to use workload identity keyvaultName: ${KEYVAULT_NAME} # Set to the name of your key vault cloudName: "" # [OPTIONAL for Azure] if not provided, the Azure environment defaults to AzurePublicCloud objects: | array: - | objectName: secret1 # Set to the name of your secret objectType: secret # object types: secret, key, or cert objectVersion: "" # [OPTIONAL] object versions, default to latest if empty - | objectName: key1 # Set to the name of your key objectType: key objectVersion: "" tenantId: "${IDENTITY_TENANT}" # The tenant ID of the key vault EOF
注意
如果您使用
objectAlias
而非objectName
,請更新 YAML 腳本來加以考慮。注意
若要讓
SecretProviderClass
正常運作,請務必在本節中objects
參考秘密、密鑰或憑證之前,先填入您的 Azure 金鑰保存庫。使用
kubectl apply
命令和下列 YAML 腳本部署範例 Pod。cat <<EOF | kubectl apply -f - # This is a sample pod definition for using SecretProviderClass and workload identity to access your key vault kind: Pod apiVersion: v1 metadata: name: busybox-secrets-store-inline-wi labels: azure.workload.identity/use: "true" spec: serviceAccountName: "workload-identity-sa" containers: - name: busybox image: registry.k8s.io/e2e-test-images/busybox:1.29-4 command: - "/bin/sleep" - "10000" volumeMounts: - name: secrets-store01-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store01-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "azure-kvname-wi" EOF
使用受控識別進行存取
Microsoft Entra 受控標識碼是系統管理員用來向其他 Azure 服務驗證自己的身分識別。 受控識別會使用 RBAC 與外部識別提供者同盟。
在此安全性模型中,您可以將叢集資源的存取權授與共享受控角色的小組成員或租使用者。 角色會檢查範圍以存取keyvault和其他認證。 當您在 AKS 叢集上啟用適用於秘密存放區 CSI 驅動程式的 Azure 金鑰保存庫 提供者時,它會建立使用者身分識別。
設定受控識別
使用
az aks show
命令和附加元件所建立的使用者指派受控識別來存取密鑰保存庫。 您也應該擷取身分識別的clientId
,您將在稍後的步驟中用來建立SecretProviderClass
。az aks show -g <resource-group> -n <cluster-name> --query addonProfiles.azureKeyvaultSecretsProvider.identity.objectId -o tsv az aks show -g <resource-group> -n <cluster-name> --query addonProfiles.azureKeyvaultSecretsProvider.identity.clientId -o tsv
或者,您可以建立新的受控識別,並使用下列命令將它指派給虛擬機器(VM) 擴展集或可用性設定組中的每個 VM 實例。
az identity create -g <resource-group> -n <identity-name> az vmss identity assign -g <resource-group> -n <agent-pool-vmss> --identities <identity-resource-id> az vm identity assign -g <resource-group> -n <agent-pool-vm> --identities <identity-resource-id> az identity show -g <resource-group> --name <identity-name> --query 'clientId' -o tsv
建立角色指派,以使用
az role assignment create
命令授與密鑰保存庫秘密、存取密鑰和憑證的身分識別許可權存取權。export IDENTITY_OBJECT_ID="$(az identity show -g <resource-group> --name <identity-name> --query 'principalId' -o tsv)" export KEYVAULT_SCOPE=$(az keyvault show --name <key-vault-name> --query id -o tsv) az role assignment create --role "Key Vault Administrator" --assignee $IDENTITY_OBJECT_ID --scope $KEYVAULT_SCOPE
SecretProviderClass
使用下列 YAML 建立 。 請務必針對userAssignedIdentityID
、keyvaultName
、tenantId
和物件使用您自己的值,以從密鑰保存庫擷取。# This is a SecretProviderClass example using user-assigned identity to access your key vault apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: azure-kvname-user-msi spec: provider: azure parameters: usePodIdentity: "false" useVMManagedIdentity: "true" # Set to true for using managed identity userAssignedIdentityID: <client-id> # Set the clientID of the user-assigned managed identity to use keyvaultName: <key-vault-name> # Set to the name of your key vault cloudName: "" # [OPTIONAL for Azure] if not provided, the Azure environment defaults to AzurePublicCloud objects: | array: - | objectName: secret1 objectType: secret # object types: secret, key, or cert objectVersion: "" # [OPTIONAL] object versions, default to latest if empty - | objectName: key1 objectType: key objectVersion: "" tenantId: <tenant-id> # The tenant ID of the key vault
注意
如果您使用
objectAlias
而非objectName
,請務必更新 YAML 腳本。注意
為了讓
SecretProviderClass
能夠正常運作,請務必在本節中objects
參考秘密、密鑰或憑證之前,先填入您的 Azure 金鑰保存庫。SecretProviderClass
使用 命令將 套用kubectl apply
至您的叢集。kubectl apply -f secretproviderclass.yaml
使用下列 YAML 建立 Pod。
# This is a sample pod definition for using SecretProviderClass and the user-assigned identity to access your key vault kind: Pod apiVersion: v1 metadata: name: busybox-secrets-store-inline-user-msi spec: containers: - name: busybox image: registry.k8s.io/e2e-test-images/busybox:1.29-4 command: - "/bin/sleep" - "10000" volumeMounts: - name: secrets-store01-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store01-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "azure-kvname-user-msi"
使用 命令將 Pod 套用
kubectl apply
至叢集。kubectl apply -f pod.yaml
驗證 金鑰保存庫 秘密
Pod 啟動之後,您可以在部署 YAML 中指定的磁碟區路徑上掛接的內容。 使用下列命令來驗證您的秘密,並列印測試秘密。
使用下列命令顯示秘密存放區中保存的秘密。
kubectl exec busybox-secrets-store-inline-user-msi -- ls /mnt/secrets-store/
使用下列命令在存放區中顯示秘密。 這個範例命令會顯示測試秘密
ExampleSecret
。kubectl exec busybox-secrets-store-inline-user-msi -- cat /mnt/secrets-store/ExampleSecret
取得憑證和金鑰
Azure 金鑰保存庫 設計會區分密鑰、秘密和憑證。 金鑰保存庫 服務的憑證功能是設計來使用密鑰和秘密功能。 當您建立金鑰保存庫憑證時,它會建立具有相同名稱的可尋址密鑰和秘密。 此密鑰允許驗證作業,而秘密允許擷取憑證值做為秘密。
金鑰保存庫憑證也包含公用 x509 憑證元數據。 金鑰保存庫會將憑證的公用和私用元件儲存在秘密中。 您可以藉由在 objectType
中 SecretProviderClass
指定 來取得每個個別元件。 下表顯示哪些物件對應至與憑證相關聯的各種資源:
Object | 傳回值 | 傳回整個憑證鏈結 |
---|---|---|
key |
公鑰,格式為 Privacy Enhanced Mail (PEM)。 | N/A |
cert |
PEM 格式的憑證。 | No |
secret |
私鑰和憑證,格式為 PEM。 | Yes |
停用現有叢集上的附加元件
注意
停用附加元件之前,請確定 未SecretProviderClass
使用中。 嘗試在 存在時 SecretProviderClass
停用附加元件會導致錯誤。
使用
az aks disable-addons
命令搭配azure-keyvault-secrets-provider
附加元件,停用現有叢集中秘密存放區 CSI 驅動程式功能的 Azure 金鑰保存庫 提供者。az aks disable-addons --addons azure-keyvault-secrets-provider -g myResourceGroup -n myAKSCluster
注意
當您停用附加元件時,現有的工作負載應該沒有任何問題,或看到掛接的秘密中的任何更新。 如果 Pod 重新啟動或建立新的 Pod 作為相應增加事件的一部分,Pod 將無法啟動,因為驅動程式不再執行。
下一步
在本文中,您已瞭解如何建立並提供身分識別來存取 Azure 金鑰保存庫。 如果您想要設定額外的組態選項或執行疑難解答,請繼續進行下一篇文章。