シークレット ストア CSI ドライバーの Azure Key Vault プロバイダーのトラブルシューティング

この記事では、Microsoft Azure Key Vault Provider for Secrets Store Container Storage Interface (CSI) Driver on Azure Kubernetes Service (AKS) を使用するときに発生する可能性がある一般的な問題について説明します。 この記事では、これらの問題を解決するためのトラブルシューティングのヒントを提供します。

前提条件

トラブルシューティング チェックリスト

Azure Key Vault ログは、プロバイダーポッドとドライバー ポッドで使用できます。 プロバイダーまたはドライバーに影響する問題をトラブルシューティングするには、アプリケーション ポッドが実行されているのと同じノードで実行されているプロバイダーまたはドライバー ポッドのログを調べます。

トラブルシューティング手順 1: シークレット ストア プロバイダー ログを確認する

アプリケーション ポッドが secrets-store-provider-azure 実行されているのと同じノードで実行されているポッドを見つけるには、アプリケーションを選択する次の kubectl get コマンドと kubectl ログ コマンドを 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 ドライバー ログを確認する

Secrets Store 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 Key Vault プロバイダーと Secrets Store CSI ドライバーからの関連ログを含めすることをお勧めします。

原因 1: キー コンテナー トークンを取得できませんでした

ログまたはイベント メッセージに次のエラー エントリが表示される場合があります。

警告 FailedMount 74s kubelet MountVolume.SetUp がボリューム "secrets-store-inline" で失敗しました: kubernetes.io/csi: mounter。SetupAt failed: rpc error: code = Unknown desc = 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 の Node Managed Identity (NMI) コンポーネントがトークン要求に関するエラー メッセージを返したために発生します。

解決策 1: NMI ポッド ログを確認する

このエラーとその解決方法の詳細については、NMI ポッド ログをチェックし、Microsoft Entraポッド ID のトラブルシューティング ガイドを参照してください。

原因 2: プロバイダー ポッドがキー コンテナー インスタンスにアクセスできない

ログまたはイベント メッセージに次のエラー エントリが表示される場合があります。

E1029 17:37:42.461313 1 server.go:54] マウント要求の処理に失敗しました。 エラー: keyvault。BaseClient#GetSecret: 要求の送信エラー: StatusCode=0 -- 元のエラー: コンテキストの期限を超えました

このエラーは、プロバイダー ポッドがキー コンテナー インスタンスにアクセスできないために発生します。 次のいずれかの理由により、アクセスが禁止される場合があります。

  • ファイアウォール規則によって、プロバイダーからのエグレス トラフィックがブロックされています。

  • AKS クラスターで構成されているネットワーク ポリシーは、エグレス トラフィックをブロックしています。

  • プロバイダー ポッドはホスト ネットワーク上で実行されます。 ポリシーがこのトラフィックをブロックしている場合、またはノードでネットワーク ジッターが発生した場合、エラーが発生する可能性があります。

解決策 2: ネットワーク ポリシー、許可リスト、ノード接続を確認する

この問題を解決するには、次のアクションを実行します。

  • プロバイダー ポッドを許可リストに配置します。

  • トラフィックをブロックするように構成されているポリシーを確認します。

  • ノードがMicrosoft Entra IDとキー コンテナーに接続されていることを確認します。

ホスト ネットワーク上で実行されているポッドから Azure キー コンテナーへの接続をテストするには、次の手順に従います。

  1. ポッドを作成します。

    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 を実行して、作成したポッドでコマンドを実行します。

    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 カスタム リソースでユーザー割り当てマネージド ID が正しくありません

"ID が見つかりません" というエラーの説明を伴う HTTP エラー コード "400" インスタンスが発生した場合、カスタム リソースで SecretProviderClass ユーザー割り当てマネージド ID が正しくありません。 完全な応答は次のテキストのようになります。

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 を更新する

適切なユーザー割り当てマネージド ID を見つけて、カスタム リソースを SecretProviderClass 更新して、パラメーターに正しい値を userAssignedIdentityID 指定します。 適切なユーザー割り当てマネージド ID を見つけるには、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設定する方法については、「シークレット ストアの CSI ドライバーの Azure Key Vault プロバイダーにアクセスするための ID を提供する」の「ユーザー割り当てマネージド ID を使用する」セクションを参照してください。

原因 4: Key Vaultプライベート エンドポイントが AKS ノードとは異なる仮想ネットワーク上にある

パブリック ネットワーク アクセスは Azure Key Vault レベルでは許可されません。AKS とKey Vault間の接続はプライベート リンクを介して行われます。 ただし、Key Vaultの 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"}

接続の問題の修正は、通常、次の 2 つの手順で行います。

  • プライベート Azure DNS ゾーン レベルで AKS クラスターの仮想ネットワークの仮想ネットワーク リンクを作成します。

  • AKS クラスターの仮想ネットワークと、Key Vault プライベート エンドポイントの仮想ネットワークの間に仮想ネットワーク ピアリングを追加します。

これらの手順については、次のセクションで詳しく説明します。

AKS クラスター ノードに接続して、Key Vaultの完全修飾ドメイン名 (FQDN) がパブリック IP アドレスまたはプライベート IP アドレスを介して解決されるかどうかを判断します。 "パブリック ネットワーク アクセスが無効になっており、要求が信頼されたサービスからではなく、承認済みのプライベート リンクを介して" というエラー メッセージを受け取った場合、Key Vault エンドポイントはパブリック 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 クラスターの仮想ネットワークの仮想ネットワーク リンクを作成します。 (Key Vault プライベート エンドポイントの仮想ネットワークに対して仮想ネットワーク リンクが自動的に作成されています)。

仮想ネットワーク リンクを作成するには、次の手順に従います。

  1. Azure portalで、[プライベート DNS ゾーン] を検索して選択します。

  2. プライベート DNS ゾーンの一覧で、プライベート DNS ゾーンの名前を選択します。 この例では、プライベート DNS ゾーンが privatelink.vaultcore.azure.net されています。

  3. プライベート DNS ゾーンのナビゲーション ウィンドウで、[ 設定] 見出しを見つけて、[ 仮想ネットワーク リンク] を選択します。

  4. 仮想ネットワーク リンクの一覧で、[追加] を選択 します

  5. [ 仮想ネットワーク リンクの追加] ページで 、次のフィールドに入力します。

    フィールド名 アクション
    リンク名 仮想ネットワーク リンクに使用する名前を入力します。
    Subscription 仮想ネットワーク リンクを含めるサブスクリプションの名前を選択します。
    仮想ネットワーク AKS クラスターの仮想ネットワークの名前を選択します。
  6. [OK] ボタンを選択します。

リンク作成手順が完了したら、 コマンドを 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: 仮想ネットワーク間の仮想ネットワーク ピアリングを追加する

プライベート エンドポイントを使用している場合は、Key Vault レベルでパブリック アクセスを無効にしている可能性があります。 そのため、AKS と Key Vaultの間に接続が存在しません。 次の Netcat (nc) コマンドを使用して、その構成をテストできます。

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

AKS と Key Vaultの間で接続できない場合は、次のテキストのような出力が表示されます。

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

AKS とKey Vault間の接続を確立するには、次の手順に従って、仮想ネットワーク間の仮想ネットワーク ピアリングを追加します。

  1. Azure portal にアクセスします。

  2. 次のいずれかのオプションを使用して、「チュートリアル: Azure portalを使用して仮想ネットワーク ピアリングで仮想ネットワークを接続する」の「仮想ネットワーク ピアの作成」セクションの手順に従って、仮想ネットワークをピアリングし、仮想ネットワークが接続されていることを確認します (一方の端から)。

    • AKS 仮想ネットワークに移動し、Key Vault プライベート エンドポイントの仮想ネットワークとピアリングします。

    • Key Vault プライベート エンドポイントの仮想ネットワークに移動し、AKS 仮想ネットワークとピアリングします。

  3. Azure portalで、他の仮想ネットワーク (前の手順でピアリングした仮想ネットワーク) の名前を検索して選択します。

  4. 仮想ネットワーク ナビゲーション ウィンドウで、[ 設定] 見出しを見つけて、[ ピアリング] を選択します。

  5. [仮想ネットワーク ピアリング] ページで、手順 2 で指定したリモート仮想ネットワークの [名前] 列にピアリング リンク名が含まれていることを確認します。 また、そのピアリング リンクの [ピアリング状態 ] 列の値が [接続済み] になっていることを確認します。

この手順を完了したら、Netcat コマンドをもう一度実行できます。 AKS とKey Vault間の DNS 解決と接続が成功します。 また、次の出力に示すように、Key Vault シークレットが正常にマウントされ、期待どおりに動作することを確認します。

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

解決策 4b: エラー コード 403 のトラブルシューティング

Azure Key Vault REST API エラー コードリファレンス記事の HTTP 403: 不十分なアクセス許可に関するセクションを確認して、エラー コード "403" のトラブルシューティングを行います。

原因 5: 登録されている CSI ドライバーの一覧に secrets-store.csi.k8s.io ドライバーがありません

ポッド イベントでドライバーが見つからない secrets-store.csi.k8s.io ことを示す次のエラー メッセージが表示された場合、アプリケーションが実行されているノードでシークレット ストア CSI ドライバー ポッドが実行されていません。

警告 FailedMount 42s (x12 over 8m56s) kubelet, akswin000000 MountVolume.SetUp がボリューム "secrets-store01-inline" で失敗しました: kubernetes.io/csi: mounter.SetUpAt が CSI クライアントを取得できませんでした: ドライバー名 secrets-store.csi.k8s.io 登録済みの CSI ドライバーの一覧に見つかりません

解決策 5a: シークレット ストア CSI ドライバーをインストールする

デプロイ マニフェストを使用してKey Vault プロバイダーをインストールした場合は、指示に従ってシークレット ストア CSI ドライバーをインストールします

解決策 5b: テイント容認を追加してシークレット ストア CSI ドライバーとKey Vault プロバイダーを再デプロイする

シークレット ストア CSI ドライバーを既にデプロイしている場合は、ノードが汚染されているかどうかをチェックします。 ノードが汚染されている場合は、テイントの容認を追加して、シークレット ストア CSI ドライバーとKey Vault プロバイダーを再デプロイします。

解決策 5c: (Windows のみ) シークレット ストア CSI ドライバーとKey Vault プロバイダーをインストールするときに Helm 構成値を使用する

アプリケーションが Windows ノードで実行されている場合は、Helm 構成値を使用して、シークレット ストア CSI ドライバーと Key Vault プロバイダーを Windows ノードにインストールします。

原因 6: ドライバーがプロバイダーと通信できない

ログまたはイベントで次のエラー メッセージが表示された場合、ドライバーはプロバイダーと通信できません。

警告 FailedMount 85s (x10 over 5m35s) kubelet, aks-default-28951543-vmss00000 MountVolume.SetUp がボリューム "secrets-store01-inline" で失敗しました: kubernetes.io/csi: mounter.SetupAt failed: rpc error: code = Unknown desc = pod default/nginx-secrets-store-inline-user-msi のシークレット ストア オブジェクトをマウントできませんでした。err: プロバイダー バイナリ azure、err: stat/etc/kubernetes/secrets-store-csi-providers/azure/provider-azure: そのようなファイルまたはディレクトリを見つけることができません

解決策 6a: (バージョン 0.0.9 より前のプロバイダー バージョン) プロバイダー ポッドがすべてのノードで実行されていることを確認する

インストールされているKey Vault プロバイダーのバージョンがバージョン 0.0.9 より前の場合は、プロバイダー ポッドがすべてのノードで実行されていることを確認します。

解決策 6b: (プロバイダー バージョン 0.0.9 以降) プロバイダー通信に gRPC を使用する

プロバイダー バージョン 0.0.9 以降Key Vaultインストールした場合は、gRPC を使用してプロバイダーと通信するようにドライバーを構成します。

原因 7: CSI ドライバーで Kubernetes シークレットを作成できない

CSI ドライバーのシークレット ストア コンテナーで次のエラー メッセージが表示される場合は、ロールベースのアクセス制御 (RBAC) クラスター ロールとクラスター ロール バインドをインストールしていません。 CSI ドライバーがマウントされたコンテンツを Kubernetes シークレットとして同期するには、クラスター ロールとクラスター ロール のバインドが必要です。

E0610 22:27:02.283100 1 secretproviderclasspodstatus_controller.go:325] "Kubernetes シークレットの作成に失敗しました" err="secrets is forbidden: User \"system:serviceaccount:default:secrets-store-csi-driver\" は API グループでリソース \"secrets\" を作成できません 名前空間 \"default\"" spc="default/azure-linux" pod="default/busybox-linux-5f479855f7-jvmfw4" secret="default/dockerconfig" spcps="default/busybox-linux-5f479855f7-jvmfw4-default-azure-linux"

解決策 7: 必要なクラスター ロールとクラスター ロール のバインドをインストールする

secrets-store-csi-driver-provider-azure GitHub リポジトリの Helm チャートを使用して CSI ドライバーとKey Vault プロバイダーをインストールまたはアップグレードする場合は、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" エラー コードで示されているように、要求はKey Vaultに対して認証されていません。

解決策 8: エラー コード 401 のトラブルシューティング

Azure Key Vault REST API エラー コードリファレンス記事の「HTTP 401: 認証されていない要求」セクションを確認して、エラー コード "401" のトラブルシューティングを行います。

原因 9: 要求の数が指定された最大値を超えています

"429" エラー コードで示されているように、要求の数が時間枠の指定された最大値を超えています。

解決策 9: エラー コードのトラブルシューティング 429

Azure Key Vault REST API エラー コードリファレンス記事の「HTTP 429: 要求が多すぎます」セクションを確認して、エラー コード "429" のトラブルシューティングを行います。

サードパーティの情報に関する免責事項

この資料に記載されているサードパーティ製品は、マイクロソフトと関連のない他社の製品です。 明示的か黙示的かにかかわらず、これらの製品のパフォーマンスや信頼性についてマイクロソフトはいかなる責任も負わないものとします。

お問い合わせはこちらから

質問がある場合やヘルプが必要な場合は、サポート要求を作成するか、Azure コミュニティ サポートにお問い合わせください。 Azure フィードバック コミュニティに製品フィードバックを送信することもできます。