共用方式為


針對 AKS 中的 Azure 金鑰保存庫 秘密提供者附加元件進行疑難解答

本文討論如何在 Azure Kubernetes Service (AKS) 中使用 Azure 金鑰保存庫 秘密提供者附加元件時遇到的問題進行疑難解答。

注意

本文適用於 Azure 金鑰保存庫 秘密提供者的 AKS 受控附加元件版本。 如果您使用已安裝的 helm(自我管理)版本,請移至 Azure 金鑰保存庫 Provider for Secrets Store CSI Driver GitHub 檔。

必要條件

疑難排解檢查清單

步驟 1:確認叢集上已啟用 Azure 金鑰保存庫 秘密提供者附加元件

執行 az aks show 命令,以確認您的叢集上已啟用附加元件:

az aks show -g <aks-resource-group-name> -n <aks-name> --query 'addonProfiles.azureKeyvaultSecretsProvider'

命令輸出應該類似下列文字:

{
  "config": null,
  "enabled": true,
  "identity": {
    "clientId": "<client-id>",
    "objectId": "<object-id>",
    "resourceId": "/subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<azure-key-vault-secrets-provider-identity-name>"
  }
}

enabled如果旗標如false上述輸出所示,則叢集上未啟用 Azure 金鑰保存庫 秘密提供者附加元件。 在此情況下,請參閱 Azure 金鑰保存庫 Provider for Secrets Store CSI Driver GitHub 檔,以取得進一步的疑難解答。

enabled如果旗標如true上述輸出所示,您的叢集上會啟用 Azure 金鑰保存庫 秘密提供者附加元件。 在此情況下,請移至本文中的後續步驟。

步驟 2:檢查秘密存放區提供者和 CSI 驅動程式 Pod 記錄

Azure 金鑰保存庫 秘密提供者附加元件記錄是由提供者和驅動程式 Pod 產生。 若要針對影響提供者或驅動程序的問題進行疑難解答,請檢查與應用程式 Pod 位於相同節點上執行的 Pod 記錄。

  1. 執行 kubectl get 命令,以尋找在應用程式 Pod 執行所在的相同節點上執行的秘密存放區提供者和 CSI 驅動程式 Pod:

    kubectl get pod -l 'app in (secrets-store-provider-azure, secrets-store-csi-driver)' -n kube-system -o wide
    
  2. 執行 kubectl logs 命令,以檢視來自秘密存放區提供者 Pod 的記錄:

    kubectl logs -n kube-system <provider-pod-name> --since=1h | grep ^E
    
  3. 執行 kubectl logs 命令,以檢視來自秘密存放區 CSI 驅動程式 Pod 的記錄:

    kubectl logs -n kube-system <csi-driver-pod-name> -c secrets-store --since=1h | grep ^E
    

收集秘密存放區提供者和 CSI 驅動程式 Pod 記錄之後,請根據下列各節所述的原因分析這些記錄,以找出問題和對應的解決方案。

注意

如果您開啟支援要求,最好包含來自 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放在allowlist上。

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

  • 請確定節點可連線到 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 金鑰保存庫 Provider for Secrets Store CSI Driver 一文中的使用使用者指派的受控識別一節。

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

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

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

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 區域的名稱。 在此範例中,私人 DNS 區域 privatelink.vaultcore.azure.net

  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

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

步驟 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

解決方案 5:針對在相同節點上執行的秘密存放區 CSI 驅動程式 Pod 進行疑難解答

執行下列命令,以擷取在相同節點上執行的秘密存放區 CSI 驅動程式 Pod 狀態:

kubectl get pod -l app=secrets-store-csi-driver -n kube-system -o wide

如果 Pod 狀態不是Running或此 Pod 中的任何容器都處於Ready狀態,請遵循檢查秘密存放區提供者和 CSI 驅動程式 Pod 記錄中的步驟,繼續檢查此 Pod 的記錄。

原因 6:找不到 SecretProviderClass

描述應用程式 Pod 時,您可能會看到下列事件:

Events:
  Type     Reason       Age               From               Message
  ----     ------       ----              ----               -------
  Warning  FailedMount  2s (x5 over 10s)  kubelet            MountVolume.SetUp failed for volume "xxxxxxx" : rpc error: code = Unknown desc = failed to get secretproviderclass xxxxxxx/xxxxxxx, error: SecretProviderClass.secrets-store.csi.x-k8s.io "xxxxxxxxxxxxx" not found

此事件表示 SecretProviderClass Pod磁碟區規格中參考的 不存在於與應用程式Pod相同的命名空間中。

解決方案 6a:建立遺漏的 SecretProviderClass 資源

請確定 SecretProviderClass Pod 磁碟區規格中參考的資源存在於應用程式 Pod 執行所在的相同命名空間中。

解決方案 6b:修改應用程式 Pod 的磁碟區規格,以參考正確的 SecretProviderClass 資源名稱

編輯應用程式 Pod 的磁碟區規格,以參考正確的 SecretProviderClass 資源名稱:

...
spec:
  containers:
  ...
  volumes:
    - name: my-volume
      csi:
        driver: secrets-store.csi.k8s.io
        readOnly: true
        volumeAttributes:
          secretProviderClass: "xxxxxxxxx"

原因 7:要求未經驗證

要求未經驗證,金鑰保存庫,如 「401」 錯誤碼所指示。

解決方案 7:疑難解答錯誤碼 401

檢閱 Azure 金鑰保存庫 REST API 錯誤碼參考文章的一節,針對錯誤碼 “401” 進行疑難解答。

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

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

解決方案 8:疑難解答錯誤碼 429

請檢閱 Azure 金鑰保存庫 REST API 錯誤碼參考文章的一節,以針對錯誤碼 “429” 進行疑難解答。

協力廠商資訊免責聲明

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

與我們連絡,以取得說明

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