共用方式為


針對適用於秘密存放區 CSI 驅動程式的 Azure 金鑰保存庫 提供者進行疑難解答

本文討論使用 Microsoft Azure 金鑰保存庫 Provider for Secrets Store 容器記憶體介面 (CSI) Driver on Azure Kubernetes Service (AKS) 時可能會遇到的常見問題。 本文提供解決這些問題的疑難解答秘訣。

必要條件

疑難解答檢查清單

Azure 金鑰保存庫 記錄可在提供者和驅動程式 Pod 中取得。 若要針對影響提供者或驅動程序的問題進行疑難解答,請檢查在應用程式 Pod 執行的相同節點上執行之提供者或驅動程式 Pod 的記錄。

疑難解答步驟 1:檢查秘密存放區提供者記錄

若要尋找在 secrets-store-provider-azure 應用程式 Pod 執行的相同節點上執行的 Pod,請執行下列 kubectl getkubectl logs 命令來選 secrets-store-provider-azure 取應用程式:

kubectl get pods --selector 'app in (csi-secrets-store-provider-azure, secrets-store-provider-azure)' \
    --all-namespaces \
    --output wide
kubectl logs <provider-pod-name> --since=1h | grep ^E

疑難解答步驟 2:檢查秘密存放區 CSI 驅動程序記錄

若要存取秘密存放區 CSI 驅動程式記錄,請執行與步驟 1 相同的命令,但改為選 secrets-store-csi-driver 取應用程式並指定 secrets-store 容器:

kubectl get pods --selector app=secrets-store-csi-driver --all-namespaces --output wide
kubectl logs <driver-pod-name> --container secrets-store --since=1h | grep ^E

注意事項

如果您開啟支援要求,最好包含來自 Azure 金鑰保存庫 提供者和秘密存放區 CSI 驅動程式的相關記錄。

原因 1:無法擷取金鑰保存庫令牌

您可能會在記錄或事件訊息中看到下列錯誤專案:

警告 FailedMount 74s kubelet MountVolume.SetUp 失敗磁碟區 “secrets-store-inline”: kubernetes.io/csi: mounter.SetupAt failed: rpc error: code = Unknown desc = failed to mount secrets store objects for Pod default/test, err: rpc error: code = Unknown desc = failed to mount objects, error: failed to get keyvault client: failed to get key vault token: nmi response failed with status code: 404, err: <nil>

發生此錯誤是因為節點受控識別 (aad-pod-identity 中的 NMI) 元件傳回令牌要求的錯誤訊息。

解決方案 1:檢查 NMI Pod 記錄

如需此錯誤及其解決方式的詳細資訊,請查看 NMI Pod 記錄,並參閱 Microsoft Entra Pod 身分識別疑難解答指南

原因 2:提供者 Pod 無法存取金鑰保存庫實例

您可能會在記錄或事件訊息中看到下列錯誤專案:

E1029 17:37:42.461313 1 server.go:54] 無法處理掛接要求, 錯誤: keyvault。BaseClient#GetSecret:傳送要求失敗:StatusCode=0 -- 原始錯誤:超過內容期限

發生此錯誤是因為提供者 Pod 無法存取金鑰保存庫實例。 存取可能會因為下列任何原因而無法存取:

  • 防火牆規則會封鎖來自提供者的輸出流量。

  • 在 AKS 叢集中設定的網路原則會封鎖輸出流量。

  • 提供者 Pod 會在主機網路上執行。 如果原則封鎖此流量,或節點上發生網路抖動,可能會發生失敗。

解決方案 2:檢查網路原則、允許清單和節點連線

若要修正此問題,請採取下列動作:

  • 將提供者Pod放在允許清單上。

  • 檢查已設定為封鎖流量的原則。

  • 請確定節點已連線到 Microsoft Entra ID和您的金鑰保存庫。

若要測試從主機網路上執行的 Pod 連線到 Azure 金鑰保存庫的連線,請遵循下列步驟:

  1. 建立 Pod:

    cat <<EOF | kubectl apply --filename -
    apiVersion: v1
    kind: Pod
    metadata:
      name: curl
    spec:
      hostNetwork: true
      containers:
      - args:
        - tail
        - -f
        - /dev/null
        image: curlimages/curl:7.75.0
        name: curl
      dnsPolicy: ClusterFirst
      restartPolicy: Always
    EOF
    
  2. 執行 kubectl exec ,以在您建立的 Pod 中執行命令:

    kubectl exec --stdin --tty  curl -- sh
    
  3. 使用您的 Azure 金鑰儲存庫進行驗證:

    curl -X POST 'https://login.microsoftonline.com/<aad-tenant-id>/oauth2/v2.0/token' \
         -d 'grant_type=client_credentials&client_id=<azure-client-id>&client_secret=<azure-client-secret>&scope=https://vault.azure.net/.default'
    
  4. 嘗試取得已在 Azure 金鑰保存庫中建立的秘密:

    curl -X GET 'https://<key-vault-name>.vault.azure.net/secrets/<secret-name>?api-version=7.2' \
         -H "Authorization: Bearer <access-token-acquired-above>"
    

原因 3:SecretProviderClass 自定義資源中的使用者指派受控識別不正確

如果您遇到伴隨「找不到身分識別」錯誤描述的 HTTP 錯誤碼 「400」 實例,則自 SecretProviderClass 定義資源中使用者指派的受控識別不正確。 完整的回應類似下列文字:

MountVolume.SetUp failed for volume "<volume-name>" :  
  rpc error:  
    code = Unknown desc = failed to mount secrets store objects for pod <namespace>/<pod>,  
    err: rpc error: code = Unknown desc = failed to mount objects,  
    error: failed to get objectType:secret, objectName:<key-vault-secret-name>, objectVersion:: azure.BearerAuthorizer#WithAuthorization:  
      Failed to refresh the Token for request to https://<key-vault-name>.vault.azure.net/secrets/<key-vault-secret-name>/?api-version=2016-10-01:  
        StatusCode=400 -- Original Error: adal: Refresh request failed.  
        Status Code = '400'.  
        Response body: {"error":"invalid_request","error_description":"Identity not found"}  
        Endpoint http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&client_id=<userAssignedIdentityID>&resource=https%!!(MISSING)A(MISSING)%!!(MISSING)F(MISSING)%!!(MISSING)F(MISSING)vault.azure.net

解決方案 3:使用正確的 userAssignedIdentityID 值更新 SecretProviderClass

尋找正確的使用者指派受控識別,然後更新 SecretProviderClass 自定義資源,以在 參數中 userAssignedIdentityID 指定正確的值。 若要尋找正確的使用者指派受控識別,請在 Azure CLI 中執行下列 az aks show 命令:

az aks show --resource-group <resource-group-name> \
    --name <cluster-name> \
    --query addonProfiles.azureKeyvaultSecretsProvider.identity.clientId \
    --output tsv

如需如何以 YAML 格式設定SecretProviderClass自訂資源的資訊,請參閱提供身分識別以存取 Azure 金鑰保存庫 秘密存放區 CSI 驅動程式提供者一文中的使用使用者指派的受控識別一節。

原因 4:金鑰保存庫 私人端點位於與 AKS 節點不同的虛擬網路上

Azure 金鑰保存庫 層級不允許公用網路存取,而且 AKS 與 金鑰保存庫 之間的連線是透過私人連結來進行。 不過,AKS 節點和 金鑰保存庫 的私人端點位於不同的虛擬網路上。 此案例會產生類似下列文字的訊息:

MountVolume.SetUp failed for volume "<volume>" :  
  rpc error:  
    code = Unknown desc = failed to mount secrets store objects for pod <namespace>/<pod>,  
    err: rpc error: code = Unknown desc = failed to mount objects,  
    error: failed to get objectType:secret, objectName: :<key-vault-secret-name>, objectVersion:: keyvault.BaseClient#GetSecret:  
      Failure responding to request:  
        StatusCode=403 -- Original Error: autorest/azure: Service returned an error.  
        Status=403 Code="Forbidden"  
        Message="Public network access is disabled and request is not from a trusted service nor via an approved private link.\r\n  
        Caller: appid=<application-id>;oid=<object-id>;iss=https://sts.windows.net/<id>/;xms_mirid=/subscriptions/<subscription-id>/resourcegroups/<aks-infrastructure-resource-group>/providers/Microsoft.Compute/virtualMachineScaleSets/aks-<nodepool-name>-<nodepool-id>-vmss;xms_az_rid=/subscriptions/<subscription-id>/resourcegroups/<aks-infrastructure-resource-group>/providers/Microsoft.Compute/virtualMachineScaleSets/aks-<nodepool-name>-<nodepool-id>-vmss \r\n  
        Vault: <keyvaultname>;location=<location>" InnerError={"code":"ForbiddenByConnection"}

修正連線問題通常是兩個步驟的程式:

下列各節將詳細說明這些步驟。

連線到 AKS 叢集節點,以判斷是否透過公用 IP 位址或私人 IP 位址解析 金鑰保存庫 的 FQDN (FQDN) 完整功能變數名稱。 如果您收到「公用網路存取已停用,且要求不是來自信任的服務,也不是透過核准的私人連結」錯誤訊息,金鑰保存庫 端點可能會透過公用IP位址解析。 若要檢查此案例,請執行 nslookup 命令:

nslookup <key-vault-name>.vault.azure.net

如果透過公用IP位址解析 FQDN,命令輸出會類似下列文字:

root@aks-<nodepool-name>-<nodepool-id>-vmss<scale-set-instance>:/# nslookup <key-vault-name>.vault.azure.net
Server:         168.63.129.16
Address:        168.63.129.16#53

Non-authoritative answer:
<key-vault-name>.vault.azure.net  canonical name = <key-vault-name>.privatelink.vaultcore.azure.net.
<key-vault-name>.privatelink.vaultcore.azure.net  canonical name = data-prod.weu.vaultcore.azure.net.
data-prod-weu.vaultcore.azure.net  canonical name = data-prod-weu-region.vaultcore.azure.net.
data-prod-weu-region.vaultcore.azure.net  canonical name = azkms-prod-weu-b.westeurope.cloudapp.azure.com.
Name:   azkms-prod-weu-b.westeurope.cloudapp.azure.com
Address: 20.1.2.3

在此情況下,請在私人 DNS 區域層級建立 AKS 叢集虛擬網路的虛擬網路連結。 (已針對 金鑰保存庫 私人端點的虛擬網路自動建立虛擬網路連結。)

若要建立虛擬網路連結,請遵循下列步驟:

  1. Azure 入口網站 中,搜尋並選取 私用 DNS 區域

  2. 在私人 DNS 區域列表中,選取私人 DNS 區域的名稱。 在此範例中,會 privatelink.vaultcore.azure.net 私人 DNS 區域。

  3. 在私人 DNS 區域的瀏覽窗格中,找出 [ 設定 ] 標題,然後選取 [ 虛擬網络連結]

  4. 在虛擬網路連結清單中,選取 [ 新增]

  5. 在 [ 新增虛擬網络連結] 頁面中,完成下列欄位。

    欄位名稱 動作
    連結名稱 輸入要用於虛擬網路連結的名稱。
    訂用帳戶 選取您想要包含虛擬網路連結的訂用帳戶名稱。
    虛擬網路 選取 AKS 叢集的虛擬網路名稱。
  6. 選取 [確定] 按鈕。

完成連結建立程序之後,請執行 nslookup 命令。 輸出現在應該類似下列文字,顯示更直接的 DNS 解析:

root@aks-<nodepool-name>-<nodepool-id>-vmss<scale-set-instance>:/# nslookup <key-vault-name>.vault.azure.net
Server:         168.63.129.16
Address:        168.63.129.16#53

Non-authoritative answer:
<key-vault-name>.vault.azure.net  canonical name = <key-vault-name>.privatelink.vaultcore.azure.net.
Name:   <key-vault-name>.privatelink.vaultcore.azure.net
Address: 172.20.0.4

新增虛擬網路連結之後,應該可以透過私人IP位址解析 FQDN。

步驟 2:在虛擬網路之間新增虛擬網路對等互連

如果您使用私人端點,您可能已停用 金鑰保存庫 層級的公用存取。 因此,AKS 與 金鑰保存庫 之間沒有連線。 您可以使用下列 Netcat (nc) 命令來測試該設定:

nc -v -w 2 <key-vault-name>.vault.azure.net 443

如果 AKS 與 金鑰保存庫 之間無法連線,您會看到類似下列文字的輸出:

nc: connect to <key-vault-name>.vault.azure.net port 443 (tcp) timed out: Operation now in progress

若要建立 AKS 與 金鑰保存庫 之間的連線,請遵循下列步驟,在虛擬網路之間新增虛擬網路對等互連:

  1. 前往 Azure 入口網站

  2. 使用下列其中一個選項,遵循教學課程:使用 Azure 入口網站 文章將虛擬網路與虛擬網路對等互連連線到虛擬網路,並確認虛擬網路已從一端連線 () 中的建立虛擬網路對等互連一節中的指示:

    • 移至您的 AKS 虛擬網路,並將它對等互連至 金鑰保存庫 私人端點的虛擬網路。

    • 移至 金鑰保存庫 私人端點的虛擬網路,並將它對等互連至 AKS 虛擬網路。

  3. 在 Azure 入口網站 中,搜尋並選取您在上一個步驟) 中對等互連之虛擬網路 (另一個虛擬網路的名稱。

  4. 在虛擬網路瀏覽窗格中,找出 [ 設定] 標題,然後選取 [ 對等互連]

  5. 在虛擬網路對等互連頁面中,確認 [名稱] 數據行包含您在步驟 2 中指定之遠端虛擬網路的對等互連連結名稱。 此外,請確定該對等互連連結的 [對 等互連狀態 ] 數據行具有 [已 連線] 值。

完成此程序之後,您可以再次執行 Netcat 命令。 AKS 與 金鑰保存庫之間的 DNS 解析和連線能力現在應該會成功。 此外,請確定已成功掛接 金鑰保存庫 秘密並如預期般運作,如下列輸出所示:

Connection to <key-vault-name>.vault.azure.net 443 port [tcp/https] succeeded!

解決方案 4b:針對錯誤碼 403 進行疑難解答

檢閱 Azure 金鑰保存庫 REST API 錯誤碼參考文章的 HTTP 403:許可權不足一節,以針對錯誤碼 “403” 進行疑難解答。

原因 5:已註冊的 CSI 驅動程式清單中遺漏 secrets-store.csi.k8s.io 驅動程式

如果您收到下列關於 Pod 事件中遺失 secrets-store.csi.k8s.io 驅動程式的錯誤訊息,則秘密存放區 CSI 驅動程式 Pod 不會在應用程式執行所在的節點上執行:

警告 FailedMount 42s (x12 over 8m56s) kubelet, akswin000000 MountVolume.SetUp 失敗磁碟區 “secrets-store01-inline”: kubernetes.io/csi: mounter.SetUpAt 無法取得 CSI 用戶端:在 已註冊的 CSI 驅動程式清單中找不到 secrets-store.csi.k8s.io 驅動程式名稱

解決方案 5a:安裝秘密存放區 CSI 驅動程式

如果您使用部署指令清單安裝 金鑰保存庫 提供者,請依照指示安裝秘密存放區 CSI 驅動程式

解決方案5b:新增 taint toleration 以重新部署秘密存放區 CSI 驅動程式和 金鑰保存庫 提供者

如果您已部署秘密存放區 CSI 驅動程式,請檢查節點是否受到保護。 如果節點已受到保護,請藉由新增容錯來重新部署秘密存放區 CSI 驅動程式和 金鑰保存庫 提供者。

解決方案5c: (Windows 在安裝秘密存放區 CSI 驅動程式和 金鑰保存庫 提供者時,僅) 使用 Helm 設定值

如果您的應用程式是在 Windows 節點上執行,請使用 Helm 組態值,在 Windows 節點上安裝秘密存放區 CSI 驅動程式和 金鑰保存庫 提供者。

原因 6:驅動程式無法與提供者通訊

如果您在記錄或事件中收到下列錯誤訊息,則驅動程式無法與提供者通訊:

警告 FailedMount 85s (x10 over 5m35s) kubelet, aks-default-28951543-vmss000000 MountVolume.SetUp failed for volume “secrets-store01-inline” : kubernetes.io/csi: mounter.SetupAt 失敗: rpc error: code = Unknown desc = failed to mount secrets store objects for Pod default/nginx-secrets-store-inline-user-msi, err: failed to find provider binary azure, err: stat /etc/kubernetes/secrets-store-csi-providers/azure/provider-azure: no such file or directory

解決方案 6a: (0.0.9 版之前的提供者版本) 確定提供者 Pod 在所有節點上執行

如果您安裝 金鑰保存庫 提供者版本早於 0.0.9 版,請確定提供者 Pod 正在所有節點上執行。

解決方案 6b: (提供者 0.0.9 版和更新版本) 使用 gRPC 進行提供者通訊

如果您已安裝 金鑰保存庫 提供者0.0.9版或更新版本,請使用 gRPC設定驅動程式以與提供者通訊。

原因 7:CSI 驅動程序無法建立 Kubernetes 秘密

如果您在 CSI 驅動程式的秘密存放區容器中收到下列錯誤訊息,則您尚未安裝角色型訪問控制 (RBAC) 叢集角色和叢集角色系結。 必須要有叢集角色和叢集角色系結,CSI 驅動程式才能將掛接的內容同步處理為 Kubernetes 秘密。

E0610 22:27:02.283100 1 secretproviderclasspodstatus_controller.go:325] “failed to create Kubernetes secret” err=“secrets is forbidden: User \”system:serviceaccount:default:secrets-store-csi-driver\“ cannot create resource \”secrets\“ in API group \”\“ in the namespace \”“ default\”“ spc=”default/azure-linux“ pod=”default/busybox-linux-5f479855f7-jvfw4“ secret=”default/dockerconfig“ spcps=”default/busybox-linux-5f479855f7-jvfw4-default-azure-linux”

解決方案7:安裝必要的叢集角色和叢集角色系結

當您從 secrets-store-csi-driver-provider-azure GitHub 存放庫使用 Helm 圖表來安裝或升級 CSI 驅動程式和 金鑰保存庫 提供者時,請將 Helm 參數設定secrets-store-csi-driver.syncSecret.enabledtrue。 此組態變更會安裝必要的叢集角色和叢集角色系結。

若要確認已安裝叢集角色和叢集角色系結,請執行下列 kubectl get 命令:

# Synchronize as Kubernetes secret cluster role.
kubectl get clusterrole/secretprovidersyncing-role

# Synchronize as Kubernetes secret cluster role binding.
kubectl get clusterrolebinding/secretprovidersyncing-rolebinding

原因 8:要求未經驗證

金鑰保存庫 的要求未經驗證,如“401” 錯誤碼所示。

解決方案8:針對錯誤碼401進行疑難解答

Troubleshoot error code "401" by reviewing the "HTTP 401: Unauthenticated Request" section of the Azure Key Vault REST API Error Codes reference article.

原因 9:要求數目超過指定的最大值

要求數目超過時間範圍的指定最大值,如“429” 錯誤碼所示。

解決方案 9:針對錯誤碼 429 進行疑難解答

Troubleshoot error code "429" by reviewing the "HTTP 429: Too Many Requests" section of the Azure Key Vault REST API Error Codes reference article.

協力廠商資訊免責聲明

本文提及的協力廠商產品是由與 Microsoft 無關的獨立廠商所製造。 Microsoft 不以默示或其他方式,提供與這些產品的效能或可靠性有關的擔保。

與我們連絡,以取得說明

如果您有問題或需要相關協助,請建立支援要求,或詢問 Azure community 支援。 您也可以將產品意見反應提交給 Azure 意應見反社群