본문 바로가기
클라우드/Azure

[Key Vault] Azure Kubernetes 내부에서 Key Vault 연동하기

by worldcenter 2025. 1. 20.

 

필수 구성 요소

  • Public한 환경의 최신 버전 Azure Kubernetes Service
  • Public한 환경의 Key Vault
  • Azure CLI 버전이 2.30.0 이상인지 확인
  • 클러스터에 대한 수신을 제한하는 경우 포트 9808 및 8095가 열려 있는지 확인

 

 

비밀 저장소 CSI 드라이버용 Azure Key Vault 공급자 지원으로 기존 AKS 클러스터 업그레이드

az aks enable-addons 추가 기능과 함께 azure-keyvault-secrets-provider 명령을 사용하여 비밀 저장소 CSI 드라이버용 Azure Key Vault 공급자 기능으로 기존 AKS 클러스터를 업그레이드합니다. 추가 기능은 Azure Key Vault에서 인증을 받는 데 사용할 수 있는 사용자가 할당한 관리 ID를 만듭니다.

az aks enable-addons --addons azure-keyvault-secrets-provider --name myAKSCluster --resource-group myResourceGroup

 

 

Azure 키 자격 증명 모음 사용

비밀 콘텐츠를 저장하는 Azure 키 자격 증명 모음 리소스가 필요합니다.

 

1. az keyvault create 명령을 사용하여 Azure Key Vault를 만듭니다. Key Vault의 이름은 전역적으로 고유해야 합니다.

az keyvault create -n <keyvault-name> -g <ResourceGroupName> -l koreacentral

 

2. Key Vault를 생성한 후 액세스 구성 > 권한 모델을 ‘자격 증명 모음 액세스 정책’으로 변경 후 저장합니다.

 

Azure 역할 기반 액세스 제어 : Azure RBAC 액세스 정책 사용
자격 증명 모음 액세스 정책 : Key Vault 액세스 정책 사용

 

3. Key Vault > 액세스 정책 > 만들기를 사용하여 본인에게 모든 권한을 부여합니다.(Secret 생성용)

 

4. Key Vault > Secret > 생성/가져오기를 통해 비밀을 하나 생성합니다. 비밀 값은 임의로 정합니다.

 

 

OIDC 발급자 활성화

Azure AD 워크로드 ID는 Pod에서 실행되는 애플리케이션이 이를 지원하는 다른 Azure 서비스(예: Storage 또는 SQL)에 대해 인증하는 데 사용하는 ID입니다. 

네이티브 Kubernetes 기능과 통합하여 외부 ID 공급자와 페더레이션합니다. 이 보안 모델에서 AKS 클러스터는 토큰 발급자 역할을 합니다. Azure Active Directory(Azure AD)는 OIDC(OpenID Connect)를 사용하여 공개 서명 키를 검색하고 서비스 계정 토큰의 신뢰성을 확인한 후 Azure AD 토큰으로 교환합니다. 

워크로드는 Azure SDK 또는 MSAL(Microsoft 인증 라이브러리)을 사용하여 Azure ID 클라이언트 라이브러리를 통해 볼륨에 프로젝션된 서비스 계정 토큰을 Azure AD 토큰으로 교환할 수 있습니다.

# 기존 AKS 클러스터 업데이트
az aks update -g <ResourceGroupName> -n <AzureKubernetesName> --enable-oidc-issuer

 

 

Azure 키 자격 증명 모음에 액세스 하기 위한 ID 제공

Azure Key Vault로 액세스 하기 위한 방법에는 4가지가 있습니다. 해당 테스트에서는 Managed Identity를 사용하여 인증을 진행합니다.

1) Pod Identity

2) Service Principal

3) User Assigned Identity

4) Managed Identity

 

1. 명령을 사용하여 구독을 az account set 설정합니다.

export SUBSCRIPTION_ID=<subscription id>
export RESOURCE_GROUP=<resource group name>
export UAMI=<name for system assigned identity>
export KEYVAULT_NAME=<existing keyvault name>
export CLUSTER_NAME=<aks cluster name>

az account set --subscription $SUBSCRIPTION_ID

 

2. 명령을 사용하여 Managed Identity(관리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. Key Vault 비밀, 액세스 키 및 인증서에 액세스할 수 있는 권한을 워크로드 ID에 부여하는 액세스 정책을 설정해야 합니다. 명령을 사용하여 이러한 권한을 할당합니다.

az keyvault set-policy -n $KEYVAULT_NAME --key-permissions get --spn $USER_ASSIGNED_CLIENT_ID
az keyvault set-policy -n $KEYVAULT_NAME --secret-permissions get --spn $USER_ASSIGNED_CLIENT_ID
az keyvault set-policy -n $KEYVAULT_NAME --certificate-permissions get --spn $USER_ASSIGNED_CLIENT_ID

 

4. 명령을 사용하여 AKS 클러스터 OIDC 발급자 URL을 가져옵니다.

export AKS_OIDC_ISSUER="$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "oidcIssuerProfile.issuerUrl" -o tsv)"
echo $AKS_OIDC_ISSUER

 

5. Azure AD 애플리케이션과 서비스 계정 발급자 및 주체 간에 페더레이션 ID 자격 증명을 설정해야 합니다. 다음 명령을 사용하여 Azure AD 애플리케이션의 개체 ID를 가져옵니다.

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}
  labels:
    azure.workload.identity/use: "true"
  name: ${SERVICE_ACCOUNT_NAME}
  namespace: ${SERVICE_ACCOUNT_NAMESPACE}
EOF

 

6. 아래 명령을 사용하여 관리 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. SecretProviderClass 명령 및 다음 YAML 스크립트를 사용하여 kubectl apply 를 배포합니다.

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-workload-identity # needs to be unique per namespace
spec:
  provider: azure
  parameters:
    usePodIdentity: "false"
    useVMManagedIdentity: "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
          objectType: secret              # object types: secret, key, or cert
          objectVersion: ""               # [OPTIONAL] object versions, default to latest if empty
        - |
          objectName: key1
          objectType: key
          objectVersion: ""
    tenantId: "${IDENTITY_TENANT}"        # The tenant ID of the key vault
EOF

 

8. 명령 및 다음 YAML 스크립트를 kubectl apply 사용하여 샘플 Pod를 배포합니다.

cat <<EOF | kubectl apply -f -
# 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
  labels:
    azure.workload.identity/use: true
spec:
  serviceAccountName: ${SERVICE_ACCOUNT_NAME}
  containers:
    - name: busybox
      image: registry.k8s.io/e2e-test-images/busybox:1.29-1 
      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-workload-identity"
EOF

 

 

비밀 유효성 검사

Pod가 시작된 후에는 배포 YAML에 지정된 볼륨 경로에 탑재된 콘텐츠를 사용할 수 있습니다.

## show secrets held in secrets-store
kubectl exec busybox-secrets-store-inline -- ls /mnt/secrets-store/

## print a test secret 'ExampleSecret' held in secrets-store
kubectl exec busybox-secrets-store-inline -- cat /mnt/secrets-store/ExampleSecret

 

 

Secret Rotation 설정 추가

Key Vault 내 키, 인증서, 비밀이 변경되었을 때 Kubernetes내 Key Vault Plugin이 변경을 감지하고 변경된 값을 가져오게 하기 위해서는 다음과 같은 설정이 필요합니다.

# 기존 AKS 클러스터에서 자동 순환 사용(기본 값 2분)
az aks addon update -g myResourceGroup -n myAKSCluster2 -a azure-keyvault-secrets-provider --enable-secret-rotation
# 사용자 지정 순환 간격 지정
az aks addon update -g myResourceGroup -n myAKSCluster2 -a azure-keyvault-secrets-provider --enable-secret-rotation --rotation-poll-interval 5m

 

 

참고 링크

https://learn.microsoft.com/ko-kr/azure/aks/csi-secrets-store-driver

 

AKS(Azure Kubernetes Service) 비밀용 비밀 저장소 CSI 드라이버에 대한 Azure Key Vault 공급자 사용 - Azure Kub

비밀 저장소 CSI 드라이버용 Azure Key Vault 공급자를 사용하여 AKS(Azure Kubernetes Service)와 비밀 저장소를 통합하는 방법을 알아봅니다.

learn.microsoft.com

https://learn.microsoft.com/ko-kr/azure/aks/csi-secrets-store-identity-access#access-with-a-user-assigned-managed-identity

 

CSI 드라이버 ID 공급자를 사용하여 Azure Key Vault에 액세스 - Azure Kubernetes Service

비밀 저장소 CSI 드라이버용 Azure Key Vault 공급자를 Azure 자격 증명 및 사용자 ID와 통합하는 방법을 알아봅니다.

learn.microsoft.com

https://learn.microsoft.com/ko-kr/azure/aks/use-oidc-issuer

 

AKS 클러스터에 대한 OpenID Connect 공급자 만들기 - Azure Kubernetes Service

AKS(Azure Kubernetes Service) 클러스터용 OIDC(OpenID Connect) 공급자를 구성하는 방법을 알아봅니다.

learn.microsoft.com

https://learn.microsoft.com/ko-kr/troubleshoot/azure/azure-kubernetes/troubleshoot-key-vault-csi-secrets-store-csi-driver

 

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

AKS(Azure Kubernetes Service)에서 Azure Key Vault 비밀 공급자 추가 기능을 사용할 때 발생하는 일반적인 문제를 해결하고 해결합니다.

learn.microsoft.com