다음을 통해 공유


기밀 컨테이너 및 기본 정책을 사용하여 AKS 클러스터 배포

이 문서에서는 Azure CLI를 사용하여 AKS(Azure Kubernetes Service) 클러스터를 배포하고 기본 보안 정책으로 기밀 컨테이너(미리 보기)를 구성합니다. 그런 다음 애플리케이션을 기밀 컨테이너로 배포합니다. 자세히 알아보려면 AKS 기밀 컨테이너 개요를 참조하세요.

일반적으로 AKS 기밀 컨테이너를 시작하려면 다음 단계를 수행해야 합니다.

  • Azure CLI를 사용하여 AKS 클러스터 배포 또는 업그레이드
  • Pod YAML 매니페스트에 주석을 추가하여 Pod가 기밀 컨테이너로 실행되는 것으로 표시합니다.
  • Pod YAML 매니페스트에 보안 정책 추가
  • 보안 정책 적용 사용
  • 기밀 컴퓨팅에 애플리케이션 배포

필수 조건

  • Azure CLI 버전 2.44.1 이상. az --version을 실행하여 버전을 찾고 az upgrade를 실행하여 버전을 업그레이드합니다. 설치 또는 업그레이드해야 하는 경우 Azure CLI 설치를 참조하세요.

  • aks-preview Azure CLI 확장 버전 0.5.169 이상.

  • confcom 기밀 컨테이너 Azure CLI 확장 0.3.3 이상. 보안 정책을 생성하려면 confcom이 필요합니다.

  • Azure 구독에 Preview 기능을 등록합니다.

  • AKS는 버전 1.25.0 이상에서 기밀 컨테이너(미리 보기)를 지원합니다.

  • 워크로드 ID 및 페더레이션된 ID 사용자 인증 정보. 워크로드 ID 자격 증명을 사용하면 Kubernetes 애플리케이션이 주석이 달린 서비스 계정을 기반으로 하는 Microsoft Entra ID를 사용하여 Azure 리소스에 안전하게 액세스할 수 있습니다. Microsoft Entra 워크로드 ID에 익숙하지 않은 경우 Microsoft Entra 워크로드 ID 개요를 참조하고 워크로드 ID가 AKS와 작동하는 방식을 검토합니다.

  • 클러스터를 만드는 데 사용하는 ID에는 적절한 최소 권한이 있습니다. AKS의 액세스 및 ID에 대한 자세한 내용은 AKS(Azure Kubernetes Service)에 대한 액세스 및 ID 옵션을 참조하세요.

  • Kubernetes 클러스터를 관리하려면 Kubernetes 명령줄 클라이언트인 kubectl을 사용합니다. Azure Cloud Shell은 kubectl과 함께 제공됩니다. az aks install-cli 명령을 사용하여 kubectl을 로컬로 설치할 수 있습니다.

  • AKS의 기밀 컨테이너는 증명 및 보안 키 릴리스를 위한 사이드카 오픈 소스 컨테이너를 제공합니다. 사이드카는 유효성 검사가 완료된 후 컨테이너 그룹에 키를 릴리스하기 위해 Azure Key Vault와 같은 KMS(키 관리 서비스)와 통합됩니다. Azure Key Vault 관리되는 HSM(하드웨어 보안 모듈) 배포는 선택 사항이지만 컨테이너 수준 무결성 및 증명을 지원하려면 권장됩니다. 관리되는 HSM을 배포하려면 관리되는 HSM 프로비전 및 활성화를 참조하세요.

aks-preview Azure CLI 확장 설치

Important

AKS 미리 보기 기능은 셀프 서비스에서 사용할 수 있습니다(옵트인 방식). 미리 보기는 "있는 그대로" 및 "사용 가능한 상태로" 제공되며 서비스 수준 계약 및 제한적 보증에서 제외됩니다. AKS 미리 보기의 일부는 고객 지원팀에서 최선을 다해 지원합니다. 따라서 이러한 기능은 프로덕션 용도로 사용할 수 없습니다. 자세한 내용은 다음 지원 문서를 참조하세요.

aks-preview 확장을 설치하려면 다음 명령을 실행합니다.

az extension add --name aks-preview

다음 명령을 실행하여 릴리스된 확장의 최신 버전으로 업데이트합니다.

az extension update --name aks-preview

confcom Azure CLI 확장 설치

confcom 확장을 설치하려면 다음 명령을 실행합니다.

az extension add --name confcom

다음 명령을 실행하여 릴리스된 확장의 최신 버전으로 업데이트합니다.

az extension update --name confcom

KataCcIsolationPreview 기능 플래그 등록

다음 예제와 같이 az feature register 명령을 사용하여 KataCcIsolationPreview 기능 플래그를 등록합니다.

az feature register --namespace "Microsoft.ContainerService" --name "KataCcIsolationPreview"

상태가 Registered로 표시되는 데 몇 분 정도 걸립니다. az feature show 명령을 사용하여 등록 상태를 확인합니다.

az feature show --namespace "Microsoft.ContainerService" --name "KataCcIsolationPreview"

상태가 등록됨으로 표시되면 az provider register 명령을 사용하여 Microsoft.ContainerService 리소스 공급자의 등록을 새로 고칩니다.

az provider register --namespace "Microsoft.ContainerService"

새 클러스터 배포

  1. az aks create 명령을 사용하고 다음 매개 변수를 지정하여 AKS 클러스터를 만듭니다.

    • --os-sku: AzureLinux. 이 미리 보기 릴리스에서는 Azure Linux os-sku만 이 기능을 지원합니다.
    • --node-vm-size: 2세대 VM이고 중첩된 가상화 작업을 지원하는 모든 Azure VM 크기입니다. 예를 들어, Standard_DC8as_cc_v5 VM입니다.
    • --enable-workload-identity: Pod가 Kubernetes ID를 사용할 수 있도록 Microsoft Entra 워크로드 ID 만들기를 사용하도록 설정합니다.
    • --enable-oidc-issuer: OIDC(OpenID Connect) 발급자를 사용하도록 설정합니다. 이를 통해 Microsoft Entra ID 또는 기타 클라우드 공급자 ID 및 액세스 관리 플랫폼에서 API 서버의 공용 서명 키를 발견할 수 있습니다.

    다음 예에서는 myAKSCluster라는 클러스터를 업데이트하고 myResourceGroup에 단일 시스템 노드 풀을 만듭니다.

    az aks create --resource-group myResourceGroup --name myAKSCluster --kubernetes-version <1.25.0 and above> --os-sku AzureLinux --node-vm-size Standard_DC4as_cc_v5 --node-count 1 --enable-oidc-issuer --enable-workload-identity --generate-ssh-keys
    

    몇 분 후 명령이 완료되면 클러스터에 대한 JSON 형식 정보가 반환됩니다. 이전 단계에서 만든 클러스터에는 노드 풀이 하나 있습니다. 다음 단계에서는 클러스터에 두 번째 노드 풀을 추가합니다.

  2. 클러스터가 준비되면 az aks get-credentials 명령을 사용하여 클러스터 자격 증명을 가져옵니다.

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
    
  3. az aks nodepool add 명령을 사용하여 myResourceGroupnodepool2에 두 개의 노드가 있는 myAKSCluster에 사용자 노드 풀을 추가합니다. 다음 매개 변수를 지정합니다.

    • --workload-runtime: 노드 풀에서 기밀 컨테이너 기능을 사용하도록 설정하려면 KataCcIsolation을 지정합니다. 이 매개 변수를 사용하면 다른 매개 변수는 다음 요구 사항을 충족해야 합니다. 그렇지 않으면 명령이 실패하고 해당 매개 변수에 문제가 보고됩니다.
    • --os-sku: AzureLinux. 이 미리 보기 릴리스에서는 Azure Linux os-sku만 이 기능을 지원합니다.
    • --node-vm-size: 2세대 VM이고 중첩된 가상화 작업을 지원하는 모든 Azure VM 크기입니다. 예를 들어, Standard_DC8as_cc_v5 VM입니다.
    az aks nodepool add --resource-group myResourceGroup --name nodepool2 --cluster-name myAKSCluster --node-count 2 --os-sku AzureLinux --node-vm-size Standard_DC4as_cc_v5 --workload-runtime KataCcIsolation
    

몇 분 후 명령이 완료되면 클러스터에 대한 JSON 형식 정보가 반환됩니다.

기존 클러스터에 배포

기존 AKS 클러스터에서 이 기능을 사용하려면 다음 요구 사항을 충족해야 합니다.

다음 명령을 사용하여 호스팅할 노드 풀을 만들어 기밀 컨테이너(미리 보기)를 사용하도록 설정합니다.

  1. az aks nodepool add 명령을 사용하여 AKS 클러스터에 노드 풀을 추가합니다. 다음 매개 변수를 지정합니다.

    • --resource-group: AKS 클러스터를 만들 기존 리소스 그룹의 이름을 입력합니다.
    • --cluster-name: AKS 클러스터의 고유한 이름(예: myAKSCluster)을 입력합니다.
    • --name: 클러스터 노드 풀의 고유한 이름을 입력합니다(예: nodepool2).
    • --workload-runtime: 노드 풀에서 기능을 사용하도록 설정하려면 KataCcIsolation을 지정합니다. --workload-runtime 매개 변수와 함께 이러한 다른 매개 변수는 다음 요구 사항을 충족해야 합니다. 그렇지 않으면 명령이 실패하고 해당 매개 변수에 문제가 보고됩니다.
    • --os-sku: AzureLinux. 이 미리 보기 릴리스에서는 Azure Linux os-sku만 이 기능을 지원합니다.
    • --node-vm-size: 2세대 VM이고 중첩된 가상화 작업을 지원하는 모든 Azure VM 크기입니다. 예를 들어, Standard_DC8as_cc_v5 VM입니다.

    다음 예에서는 myResourceGroupnodepool2에 두 개의 노드가 있는 myAKSCluster에 사용자 노드 풀을 추가합니다.

    az aks nodepool add --resource-group myResourceGroup --name nodepool2 –-cluster-name myAKSCluster --node-count 2 --os-sku AzureLinux --node-vm-size Standard_DC4as_cc_v5 --workload-runtime KataCcIsolation
    

    몇 분 후 명령이 완료되면 클러스터에 대한 JSON 형식 정보가 반환됩니다.

  2. az aks update 명령을 실행하여 클러스터에서 기밀 컨테이너(미리 보기)를 사용하도록 설정합니다.

    az aks update --name myAKSCluster --resource-group myResourceGroup
    

    몇 분 후 명령이 완료되면 클러스터에 대한 JSON 형식 정보가 반환됩니다.

  3. 클러스터가 준비되면 az aks get-credentials 명령을 사용하여 클러스터 자격 증명을 가져옵니다.

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
    

컨테이너 구성

Azure Key Vault 및 비밀에 대한 액세스를 구성하고 애플리케이션을 기밀 컨테이너로 배포하기 전에 워크로드 ID 구성을 완료해야 합니다.

워크로드 ID를 구성하려면 워크로드 ID 배포 및 구성 문서에 설명된 다음 단계를 수행합니다.

  • OIDC 발급자 URL 찾기
  • 관리 ID 만들기
  • Kubernetes 서비스 계정 만들기
  • 페더레이션 ID 자격 증명 설정

Important

이 자습서를 계속 완료하려면 워크로드 ID 배포 및 구성 문서의 환경 변수 내보내기 섹션에서 환경 변수를 설정해야 합니다. 워크로드 ID를 구성하기 전에 SERVICE_ACCOUNT_NAMESPACE 변수를 kafka로 설정하고 kubectl create namespace kafka 명령을 실행해야 합니다.

kata-cc 및 증명 컨테이너를 사용하여 신뢰할 수 있는 애플리케이션 배포

다음 단계에서는 Azure 관리 하드웨어 보안 모듈(mHSM)에서 관리하는 암호화 키를 사용하여 Kafka 메시지에 대한 엔드투엔드 암호화를 구성합니다. 키는 Kafka 소비자가 Pod에 삽입된 Azure Attestation 비밀 프로비전 컨테이너를 사용하여 기밀 컨테이너 내에서 실행되는 경우에만 해제됩니다.

이 구성은 다음 네 가지 구성 요소를 기반으로 합니다.

  • Kafka 클러스터: 클러스터의 Kafka 네임스페이스에 배포된 간단한 Kafka 클러스터입니다.
  • Kafka 생산자: 공개 키를 사용하여 암호화된 사용자 구성 메시지를 Kafka 항목에 보내는 Vanilla Kubernetes Pod로 실행되는 Kafka 생산자입니다.
  • Kafka 소비자: Kafka 메시지를 해독하기 위한 프라이빗 키를 검색하고 메시지를 웹 UI에 렌더링하는 보안 키 릴리스 컨테이너가 장착된 kata-cc 런타임으로 실행되는 Kafka 소비자 Pod입니다.

이 미리 보기 릴리스에서는 테스트 및 평가 목적으로 기존 Azure Key Vault 프리미엄 계층 리소스를 만들거나 사용하여 HSM(하드웨어 보안 모듈)에 키 저장을 지원하는 것이 좋습니다. 프로덕션 키 자격 증명 모음을 사용하지 않는 것이 좋습니다. Azure Key Vault가 없으면 Azure CLI를 사용하여 Key Vault 만들기를 참조하세요.

  1. 이전에 만든 관리 ID와 계정에 키 자격 증명 모음에 대한 액세스 권한을 부여합니다. 두 ID 모두에 Key Vault 암호화 담당자Key Vault 암호화 사용자 Azure RBAC 역할을 할당합니다.

    참고 항목

    • 관리 ID는 USER_ASSIGNED_IDENTITY_NAME 변수에 할당하는 값입니다.

    • 역할 할당을 추가하려면 Key Vault 데이터 액세스 관리자, 사용자 액세스 관리자 또는 소유자와 같은 Microsoft.Authorization/roleAssignments/writeMicrosoft.Authorization/roleAssignments/delete 권한이 있어야 합니다.

    • HSM 보호 키를 지원하려면 Key Vault Premium SKU를 사용해야 합니다.

    범위를 설정하려면 다음 명령을 실행합니다.

    AKV_SCOPE=$(az keyvault show --name <AZURE_AKV_RESOURCE_NAME> --query id --output tsv)
    

    다음 명령을 실행하여 Key Vault 암호화 담당자 역할을 할당합니다.

    az role assignment create --role "Key Vault Crypto Officer" --assignee "${USER_ASSIGNED_IDENTITY_NAME}" --scope $AKV_SCOPE
    

    다음 명령을 실행하여 Key Vault 암호화 사용자 역할을 할당합니다.

    az role assignment create --role "Key Vault Crypto User" --assignee "${USER_ASSIGNED_IDENTITY_NAME}" --scope $AKV_SCOPE
    
  2. 다음 명령을 실행하여 kafka 네임스페이스에 Kafka 클러스터를 설치합니다.

    kubectl create -f 'https://strimzi.io/install/latest?namespace=kafka' -n kafka
    
  3. 다음 명령을 실행하여 kafka 클러스터 CR 파일을 적용합니다.

    kubectl apply -f https://strimzi.io/examples/latest/kafka/kafka-persistent-single.yaml -n kafka
    
  4. GitHub의 워크로드에 대해 bash 스크립트를 사용하여 RSA 암호화/복호화 키를 준비합니다. 파일을 setup-key.sh로 저장합니다.

  5. 다음 명령을 실행하여 증명 URI의 FQDN으로 MAA_ENDPOINT 환경 변수를 설정합니다.

    export MAA_ENDPOINT="$(az attestation show --name "myattestationprovider" --resource-group "MyResourceGroup" --query 'attestUri' -o tsv | cut -c 9-)"
    

    증명 URI의 FQDN이 올바른 형식인지 확인합니다(MAA_ENDPOINT에 접두사 "https://"가 포함되어서는 안 됨).

    echo $MAA_ENDPOINT
    

    참고 항목

    Microsoft Azure Attestation을 설정하려면 빠른 시작: Azure CLI를 사용하여 Azure Attestation 설정을 참조하세요.

  6. 다음 YAML 매니페스트를 복사하여 consumer.yaml로 저장합니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: kafka-golang-consumer
      namespace: kafka
      labels:
        azure.workload.identity/use: "true"
        app.kubernetes.io/name: kafka-golang-consumer
    spec:
      serviceAccountName: workload-identity-sa
      runtimeClassName: kata-cc-isolation
      containers:
        - image: "mcr.microsoft.com/aci/skr:2.7"
          imagePullPolicy: Always
          name: skr
          env:
            - name: SkrSideCarArgs
              value: ewogICAgImNlcnRjYWNoZSI6IHsKCQkiZW5kcG9pbnRfdHlwZSI6ICJMb2NhbFRISU0iLAoJCSJlbmRwb2ludCI6ICIxNjkuMjU0LjE2OS4yNTQvbWV0YWRhdGEvVEhJTS9hbWQvY2VydGlmaWNhdGlvbiIKCX0gIAp9
          command:
            - /bin/skr
          volumeMounts:
            - mountPath: /opt/confidential-containers/share/kata-containers/reference-info-base64
              name: endor-loc
        - image: "mcr.microsoft.com/acc/samples/kafka/consumer:1.0"
          imagePullPolicy: Always
          name: kafka-golang-consumer
          env:
            - name: SkrClientKID
              value: kafka-encryption-demo
            - name: SkrClientMAAEndpoint
              value: sharedeus2.eus2.test.attest.azure.net
            - name: SkrClientAKVEndpoint
              value: "myKeyVault.vault.azure.net"
            - name: TOPIC
              value: kafka-demo-topic
          command:
            - /consume
          ports:
            - containerPort: 3333
              name: kafka-consumer
          resources:
            limits:
              memory: 1Gi
              cpu: 200m
      volumes:
        - name: endor-loc
          hostPath:
            path: /opt/confidential-containers/share/kata-containers/reference-info-base64
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: consumer
      namespace: kafka
    spec:
      type: LoadBalancer
      selector:
        app.kubernetes.io/name: kafka-golang-consumer
      ports:
        - protocol: TCP
          port: 80
          targetPort: kafka-consumer
    

    참고 항목

    프로토콜 값 https://를 제외하고 Azure Key Vault의 URL과 일치하도록 Pod 환경 변수 SkrClientAKVEndpoint의 값을 업데이트합니다. 현재 값 자리 표시자 값은 myKeyVault.vault.azure.net입니다. Pod 환경 변수 SkrClientMAAEndpoint의 값을 MAA_ENDPOINT 값으로 업데이트합니다. echo $MAA_ENDPOINT 명령 또는 az attestation show --name "myattestationprovider" --resource-group "MyResourceGroup" --query 'attestUri' -o tsv | cut -c 9- 명령을 실행하여 MAA_ENDPOINT의 값을 찾을 수 있습니다.

  7. 다음 명령을 실행하여 Kafka 소비자 YAML 매니페스트에 대한 보안 정책을 생성하고 WORKLOAD_MEASUREMENT 변수에 저장된 보안 정책의 해시를 가져옵니다.

    export WORKLOAD_MEASUREMENT=$(az confcom katapolicygen -y consumer.yaml --print-policy | base64 -d | sha256sum | cut -d' ' -f1)
    
  8. RSA 비대칭 키 쌍(공용 및 프라이빗 키)을 생성하려면 다음 명령을 사용하여 setup-key.sh 스크립트를 실행합니다. <Azure Key Vault URL> 값은 <your-unique-keyvault-name>.vault.azure.net이어야 합니다.

    export MANAGED_IDENTITY=${USER_ASSIGNED_CLIENT_ID}
    bash setup-key.sh "kafka-encryption-demo" <Azure Key Vault URL>
    

    참고 항목

    • bash 스크립트 setup-key.sh에는 환경 변수 MANAGED_IDENTITY가 필요합니다.

    • bash 스크립트를 실행한 후 공개 키는 kafka-encryption-demo-pub.pem으로 저장됩니다.

    Important

    ForbiddenByRbac 오류가 수신되면 관리 ID에 대한 백 엔드 서비스가 리소스 URI당 캐시를 최대 24시간 동안 유지하므로 최대 24시간을 기다려야 할 수 있습니다. Azure RBAC 문제 해결도 참조하세요.

  9. 키가 키 자격 증명 모음에 성공적으로 업로드되었는지 확인하려면 다음 명령을 실행합니다.

    az account set --subscription <Subscription ID>
    az keyvault key list --vault-name <KeyVault Name> -o table
    
  10. 다음 YAML 매니페스트를 복사하여 producer.yaml로 저장합니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: kafka-producer
      namespace: kafka
    spec:
      containers:
        - image: "mcr.microsoft.com/acc/samples/kafka/producer:1.0"
          name: kafka-producer
          command:
            - /produce
          env:
            - name: TOPIC
              value: kafka-demo-topic
            - name: MSG
              value: "Azure Confidential Computing"
            - name: PUBKEY
              value: |-
                -----BEGIN PUBLIC KEY-----
                MIIBojAN***AE=
                -----END PUBLIC KEY-----
          resources:
            limits:
              memory: 1Gi
              cpu: 200m
    

    참고 항목

    -----BEGIN PUBLIC KEY-----로 시작하고 -----END PUBLIC KEY----- 문자열로 끝나는 값을 이전 단계에서 만들어진 kafka-encryption-demo-pub.pem의 콘텐츠로 업데이트합니다.

  11. 이전에 저장한 파일을 사용하여 consumerproducer YAML 매니페스트를 배포합니다.

    kubectl apply -f consumer.yaml
    
    kubectl apply -f producer.yaml
    
  12. 다음 명령을 사용하여 웹 서비스의 IP 주소를 가져옵니다.

    kubectl get svc consumer -n kafka
    
  13. 소비자 서비스의 외부 IP 주소를 복사하여 브라우저에 붙여넣고 해독된 메시지를 관찰합니다.

    다음 예에서는 명령의 출력과 유사합니다.

    Welcome to Confidential Containers on AKS!
    Encrypted Kafka Message:
    Msg 1: Azure Confidential Computing
    
  14. 또한 skr containerkata-cc runtime class 사양을 제거하여 소비자를 일반 Kubernetes Pod로 실행해야 합니다. kata-cc 런타임 클래스를 사용하여 소비자를 실행하지 않으므로 더 이상 정책이 필요하지 않습니다.

  15. 워크로드를 다시 배포한 후 전체 정책을 제거하고 브라우저에서 메시지를 다시 관찰합니다. 프라이빗 암호화 키를 검색할 수 없기 때문에 메시지는 base64로 인코딩된 암호 텍스트로 나타납니다. 소비자가 더 이상 기밀 환경에서 실행되지 않고 skr container가 누락되어 메시지를 해독할 수 없기 때문에 키를 검색할 수 없습니다.

정리

이 기능 평가를 마쳤으면 Azure 요금이 청구되지 않도록 불필요한 리소스를 정리합니다. 평가 또는 테스트의 일부로 새 클러스터를 배포한 경우 az aks delete 명령을 사용하여 클러스터를 삭제할 수 있습니다.

az aks delete --resource-group myResourceGroup --name myAKSCluster

기존 클러스터에서 기밀 컨테이너(미리 보기)를 사용하도록 설정한 경우 kubectl delete pod 명령을 사용하여 Pod를 제거할 수 있습니다.

kubectl delete pod pod-name

다음 단계

  • 하드웨어 격리를 사용하고 Azure 플랫폼 유지 관리 이벤트를 제어하기 위한 AKS 클러스터가 있는 노드용 Azure Dedicated Host에 대해 자세히 알아봅니다.