다음을 통해 공유


AKS에서 Azure Key Vault 비밀 공급자 추가 기능 문제 해결

이 문서에서는 AKS(Azure Kubernetes Service)에서 Azure Key Vault 비밀 공급자 추가 기능을 사용할 때 발생할 수 있는 문제를 해결하는 방법을 설명합니다.

참고 항목

이 문서는 Azure Key Vault 비밀 공급자의 AKS 관리되는 추가 기능 버전에 적용됩니다. Helm 설치(자체 관리) 버전을 사용하는 경우 Azure Key Vault Provider for Secrets Store CSI 드라이버 GitHub 설명서로 이동합니다.

필수 조건

문제 해결 검사 목록

1단계: 클러스터에서 Azure Key Vault 비밀 공급자 추가 기능이 사용하도록 설정되어 있는지 확인

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 Key Vault 비밀 공급자 추가 기능을 사용할 수 없습니다. 이 경우 추가 문제 해결을 위해 비밀 저장소 CSI 드라이버 GitHub 설명서에 대한 Azure Key Vault 공급자를 참조하세요.

enabled 이전 출력에서와 같이 true 플래그가 표시되면 클러스터에서 Azure Key Vault 비밀 공급자 추가 기능이 사용하도록 설정됩니다. 이 경우 이 문서의 다음 단계로 이동합니다.

2단계: 비밀 저장소 공급자 및 CSI 드라이버 Pod 로그 확인

Azure Key Vault 비밀 공급자 추가 기능 로그는 공급자와 드라이버 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 Key Vault 공급자 및 비밀 저장소 CSI 드라이버의 관련 로그를 포함하는 것이 좋습니다.

원인 1: 키 자격 증명 모음 토큰을 가져올 수 없음

로그 또는 이벤트 메시지에 다음 오류 항목이 표시될 수 있습니다.

경고 FailedMount 74s kubelet MountVolume.SetUp이 볼륨 "secrets-store-inline" : kubernetes.io/csi: 탑재자에 대해 실패했습니다. SetupAt 실패: rpc 오류: 코드 = 알 수 없는 desc = Pod 기본/테스트에 대한 비밀 저장소 개체를 탑재하지 못했습니다. err: rpc 오류: 코드 = 알 수 없는 desc = 개체 를 탑재하지 못했습니다. 오류: keyvault 클라이언트를 가져오지 못했습니다. 키 자격 증명 모음 토큰을 가져오지 못했습니다. 상태 코드로 nmi 응답 실패: 404, err: <nil>

이 오류는 aad-pod-identity의 NMI(노드 관리 ID) 구성 요소가 토큰 요청에 대한 오류 메시지를 반환했기 때문에 발생합니다.

해결 방법 1: NMI Pod 로그 확인

이 오류 및 해결 방법에 대한 자세한 내용은 NMI Pod 로그를 확인하고 Microsoft Entra Pod ID 문제 해결 가이드를 참조하세요.

원인 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 Key Vault에 대한 연결을 테스트하려면 다음 단계를 수행합니다.

  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 Key Vault를 사용하여 인증:

    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 Key Vault에서 이미 만든 비밀을 가져옵니다.

    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 사용자 지정 리소스를 설정하는 방법에 대한 자세한 내용은 ID 제공의 사용자 할당 관리 ID 사용 섹션을 참조하여 Azure Key Vault Provider for Secrets Store CSI 드라이버 문서에 액세스합니다.

원인 4: Key Vault의 프라이빗 엔드포인트가 AKS 노드와 다른 가상 네트워크에 위치함

공용 네트워크 액세스는 Azure Key Vault 수준에서 허용되지 않으며 AKS와 Key Vault 간의 연결은 프라이빗 링크를 통해 이루어집니다. 그러나 AKS 노드와 Key Vault의 프라이빗 엔드포인트는 서로 다른 가상 네트워크에 있습니다. 이 시나리오에서는 다음 텍스트와 유사한 메시지를 생성합니다.

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단계 프로세스입니다.

각 단계에 대해서는 다음 섹션에서 자세하게 설명합니다.

AKS 클러스터 노드에 연결하여 Key Vault의 FQDN(정규화된 도메인 이름)이 공용 IP 주소 또는 개인 IP 주소를 통해 확인되는지 여부를 확인합니다 . "공용 네트워크 액세스가 비활성화되고 요청이 신뢰할 수 있는 서비스 또는 승인된 프라이빗 링크를 통해서가 아닙니다" 오류 메시지가 표시되는 경우 Key Vault 엔드포인트는 공용 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 클러스터의 가상 네트워크에 대한 가상 네트워크 링크를 만듭니다. (Key Vault 프라이빗 엔드포인트의 가상 네트워크에 대한 가상 네트워크 링크가 이미 자동으로 만들어집니다.)

가상 네트워크 링크를 만들려면 다음 단계를 따릅니다.

  1. Azure Portal에서 프라이빗 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

가상 네트워크 링크가 추가된 후 개인 IP 주소를 통해 FQDN을 확인할 수 있어야 합니다.

2단계: 가상 네트워크 간에 가상 네트워크 피어링 추가

프라이빗 엔드포인트를 사용하는 경우 Key Vault 수준에서 공용 액세스를 사용하지 않도록 설정했을 수 있습니다. 따라서 AKS와 Key Vault 간에 연결이 없습니다. 다음 nc(Netcat) 명령을 사용하여 해당 구성을 테스트할 수 있습니다.

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 드라이버가 없음

Pod 이벤트에서 누락된 secrets-store.csi.k8s.io 드라이버에 대한 다음 오류 메시지가 표시되면 비밀 저장소 CSI 드라이버 Pod가 애플리케이션이 실행 중인 노드에서 실행되지 않습니다.

경고 FailedMount 42s(x12 over 8m56s) kubelet, akswin000000 MountVolume.SetUp이 볼륨 "secrets-store01-inline": kubernetes.io/csi: 탑재자에 대해 실패했습니다. 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

이 이벤트는 Pod의 볼륨 사양에서 참조된 항목이 SecretProviderClass 애플리케이션 Pod와 동일한 네임스페이스에 존재하지 않음을 나타냅니다.

솔루션 6a: 누락된 SecretProviderClass 리소스 만들기

Pod의 볼륨 사양에서 참조되는 리소스가 애플리케이션 Pod가 실행 중인 동일한 네임스페이스에 있는지 확인 SecretProviderClass 합니다.

솔루션 6b: 올바른 SecretProviderClass 리소스 이름을 참조하도록 애플리케이션 Pod의 볼륨 사양 수정

올바른 SecretProviderClass 리소스 이름을 참조하도록 애플리케이션 Pod의 볼륨 사양을 편집합니다.

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

원인 7: 요청이 인증되지 않음

요청은 "401" 오류 코드로 표시된 대로 Key Vault에 대해 인증되지 않습니다.

해결 방법 7: 오류 코드 401 문제 해결

Azure Key Vault REST API 오류 코드 참조 문서의 "HTTP 401: 인증되지 않은 요청" 섹션을 검토하여 오류 코드 "401"을 해결합니다.

원인 8: 요청 수가 명시된 최대값을 초과합니다.

요청 수가 "429" 오류 코드에 표시된 대로 지정된 시간 범위의 최대값을 초과합니다.

해결 방법 8: 오류 코드 429 문제 해결

Azure Key Vault REST API 오류 코드 참조 문서의 "HTTP 429: 너무 많은 요청" 섹션을 검토하여 오류 코드 "429"를 해결합니다.

타사 정보 고지 사항

이 문서에 나와 있는 다른 공급업체 제품은 Microsoft와 무관한 회사에서 제조한 것입니다. Microsoft는 이들 제품의 성능이나 안정성에 관하여 명시적이든 묵시적이든 어떠한 보증도 하지 않습니다.

도움을 요청하십시오.

질문이 있거나 도움이 필요한 경우 지원 요청을 생성하거나Azure 커뮤니티 지원에 문의하세요. Azure 피드백 커뮤니티에 제품 피드백을 제출할 수도 있습니다.