AZURE ID 공급자를 AKS(Azure Kubernetes Service)의 Azure Key Vault 비밀 저장소 CSI 드라이버에 커넥트

AKS(Azure Kubernetes Service)의 CSI(비밀 저장소 컨테이너 스토리지 인터페이스) 드라이버는 Azure Key Vault에 대한 다양한 ID 기반 액세스 방법을 제공합니다. 이 문서에서는 RBAC(역할 기반 액세스 제어) 또는 OIDC(OpenID 커넥트) 보안 모델을 사용하여 키 자격 증명 모음 및 AKS 클러스터에 액세스하는 경우에 대한 이러한 방법과 모범 사례를 간략하게 설명합니다.

다음 액세스 방법 중 하나를 사용할 수 있습니다.

CSI 드라이버의 필수 구성 요소

Microsoft Entra 워크로드 ID 사용하여 액세스

Microsoft Entra 워크로드 ID Pod에서 실행되는 애플리케이션이 소프트웨어의 워크로드와 같은 다른 Azure 서비스에 대해 자신을 인증하는 데 사용하는 ID입니다. 비밀 저장소 CSI 드라이버는 네이티브 Kubernetes 기능과 통합되어 외부 ID 공급자와 페더레이션됩니다.

이 보안 모델에서 AKS 클러스터는 토큰 발급자 역할을 합니다. 그런 다음 Microsoft Entra ID는 OIDC를 사용하여 공개 서명 키를 검색하고 Microsoft Entra 토큰으로 교환하기 전에 서비스 계정 토큰의 신뢰성을 확인합니다. 워크로드가 Microsoft Entra 토큰의 볼륨에 프로젝트된 서비스 계정 토큰을 교환하려면 Azure SDK 또는 MSAL(Microsoft 인증 라이브러리)의 Azure ID 클라이언트 라이브러리가 필요합니다.

참고 항목

  • 이 인증 방법은 Microsoft Entra Pod 관리 ID(미리 보기)를 대체합니다. Azure Kubernetes Service의 오픈 소스 Microsoft Entra Pod 관리 ID(미리 보기)는 2022년 10월 24일부터 더 이상 사용되지 않습니다.
  • Microsoft Entra 워크로드 ID Windows 및 Linux 클러스터를 모두 지원합니다.

워크로드 ID 구성

  1. 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
    
  2. az identity create 명령을 사용하여 관리 ID를 만듭니다.

    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)
    
  3. az role assignment create 명령을 사용하여 키 자격 증명 모음 비밀, 액세스 키 및 인증서에 액세스할 수 있는 워크로드 ID 권한을 부여하는 역할 할당을 만듭니다.

    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
    
  4. 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
    
  5. Microsoft Entra 애플리케이션, 서비스 계정 발급자 및 주체 간에 페더레이션 ID 자격 증명을 설정합니다. 다음 명령을 사용하여 Microsoft Entra 애플리케이션의 개체 ID를 가져옵니다. Kubernetes 서비스 계정 이름과 해당 네임스페이스로 serviceAccountNameserviceAccountNamespace의 값을 업데이트해야 합니다.

    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
    
  6. az identity federated-credential create 명령을 사용하여 관리 ID, 서비스 계정 발급자 및 주체 간의 페더레이션된 ID 자격 증명을 만듭니다.

    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}
    
  7. kubectl apply 명령과 다음 YAML 스크립트를 사용하여 SecretProviderClass를 배포합니다.

    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
    

    참고 항목

    대신 objectName사용하는 objectAlias 경우 YAML 스크립트를 업데이트하여 설명합니다.

    참고 항목

    제대로 작동하려면 SecretProviderClass 섹션에서 참조하기 전에 Azure Key Vault를 비밀, 키 또는 인증서로 채워야 합니다 objects .

  8. 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
    

관리 ID를 사용하여 액세스

Microsoft Entra 관리 ID는 관리자가 다른 Azure 서비스에 대해 자신을 인증하는 데 사용하는 ID입니다. 관리 ID는 RBAC를 사용하여 외부 ID 공급자와 페더레이션합니다.

이 보안 모델에서는 관리되는 역할을 공유하는 팀 구성원 또는 테넌트에 클러스터의 리소스에 대한 액세스 권한을 부여할 수 있습니다. 역할은 keyvault 및 기타 자격 증명에 액세스하는 범위에 대해 검사. AKS 클러스터에서 비밀 저장소 CSI 드라이버에 대한 Azure Key Vault 공급자를 사용하도록 설정하면 사용자 ID가 생성됩니다.

관리 ID 구성

  1. 추가 기능에서 az aks show 만든 명령 및 사용자 할당 관리 ID를 사용하여 키 자격 증명 모음에 액세스합니다. 또한 ID clientId를 검색해야 합니다. 이 ID는 만들 때 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
    

    또는 다음 명령을 사용하여 새 관리 ID를 만들고 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
    
  2. 명령을 사용하여 키 자격 증명 모음 비밀, 액세스 키 및 인증서에 대한 액세스 권한을 ID에 부여하는 역할 할당을 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
    
  3. 다음 YAML을 사용하여 SecretProviderClass를 만듭니다. 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
    

    참고 항목

    대신 objectName사용하는 objectAlias 경우 YAML 스크립트를 업데이트해야 합니다.

    참고 항목

    제대로 작동하려면 SecretProviderClass 섹션에서 참조하기 전에 Azure Key Vault를 비밀, 키 또는 인증서로 채워야 합니다 objects .

  4. kubectl apply 명령을 사용하여 클러스터에 SecretProviderClass를 적용합니다.

    kubectl apply -f secretproviderclass.yaml
    
  5. 다음 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"
    
  6. kubectl apply 명령을 사용하여 클러스터에 Pod를 적용합니다.

    kubectl apply -f pod.yaml
    

Key Vault 비밀 유효성 검사

Pod가 시작된 후에는 배포 YAML에 지정된 볼륨 경로에 탑재된 콘텐츠를 사용할 수 있습니다. 다음 명령을 사용하여 비밀의 유효성을 검사하고 테스트 비밀을 인쇄합니다.

  1. 다음 명령을 사용하여 비밀 저장소에 보관된 비밀을 표시합니다.

    kubectl exec busybox-secrets-store-inline-user-msi -- ls /mnt/secrets-store/
    
  2. 다음 명령을 사용하여 저장소에 비밀을 표시합니다. 이 예제 명령은 테스트 비밀을 ExampleSecret보여줍니다.

    kubectl exec busybox-secrets-store-inline-user-msi -- cat /mnt/secrets-store/ExampleSecret
    

인증서 및 키 가져오기

Azure Key Vault 디자인은 키, 비밀 및 인증서를 뚜렷하게 구분합니다. Key Vault 서비스의 인증서 기능은 키 및 비밀 기능을 사용하도록 설계되었습니다. 키 자격 증명 모음 인증서를 만들 때 동일한 이름으로 주소 지정 가능한 키와 비밀을 만듭니다. 이 키는 인증 작업을 허용하고 비밀은 인증서 값을 비밀로 검색할 수 있도록 합니다.

키 자격 증명 모음 인증서에는 공용 x509 인증서 메타데이터도 포함됩니다. 키 자격 증명 모음은 인증서의 퍼블릭 및 프라이빗 구성 요소를 모두 비밀에 저장합니다. SecretProviderClassobjectType을(를) 지정하여 각 개별 구성 요소를 가져올 수 있습니다. 다음 표에서는 인증서와 연결된 다양한 리소스에 매핑되는 개체를 보여 줍니다.

Object 반환 값 전체 인증서 체인을 반환합니다.
key PEM(Privacy Enhanced Mail) 형식의 공개 키입니다. 해당 없음
cert PEM 형식의 인증서입니다. 아니요
secret PEM 형식의 프라이빗 키 및 인증서입니다.

기존 클러스터에서 추가 기능 사용 안 함

참고 항목

추가 기능을 사용하지 않도록 설정하기 전에 사용 중인 항목이 없는지SecretProviderClass 확인합니다. 있는 동안 SecretProviderClass 추가 기능을 사용하지 않도록 설정하면 오류가 발생합니다.

  • 추가 기능과 함께 명령을 사용하여 az aks disable-addons 기존 클러스터에서 비밀 저장소 CSI 드라이버 기능에 대한 Azure Key Vault 공급자를 azure-keyvault-secrets-provider 사용하지 않도록 설정합니다.

    az aks disable-addons --addons azure-keyvault-secrets-provider -g myResourceGroup -n myAKSCluster
    

참고 항목

추가 기능을 사용하지 않도록 설정하면 기존 워크로드에 문제가 없거나 탑재된 비밀에 업데이트가 표시되어야 합니다. Pod가 다시 시작되거나 확장 이벤트의 일부로 새 Pod가 만들어지면 드라이버가 더 이상 실행되지 않으므로 Pod가 시작되지 않습니다.

다음 단계

이 문서에서는 Azure Key Vault에 액세스하기 위한 ID를 만들고 제공하는 방법을 알아보았습니다. 추가 구성 옵션을 구성하거나 문제 해결을 수행하려면 다음 문서를 계속 진행합니다.