워크로드 아이덴티티

이 페이지에서는 GKE 애플리케이션이 Google API에서 제공하는 서비스를 사용하는 권장 방법을 설명합니다. 이를 위해 Google 서비스 계정 역할을 하도록 Kubernetes 서비스 계정을 구성합니다. 그러면 Kubernetes 서비스 계정으로 실행되는 모든 Pod는 Google 계정을 사용하여 클라우드 서비스를 인증합니다.

개요

워크로드 아이덴티티는 향상된 보안 속성 및 관리 편의성으로 인해 GKE 내에서 Google Cloud 서비스에 액세스하는 데 권장되는 방식입니다. 자세한 내용은 아래 대안을 참조하세요.

GKE에서 실행되는 워크로드는 Compute API, Storage 및 Database API, Machine Learning API와 같은 Google Cloud API를 사용하도록 인증해야 합니다. Kubernetes 서비스 계정과 Google 서비스 계정 간의 관계를 구성하면 Kubernetes 서비스 계정으로 실행되는 모든 워크로드는 Google Cloud API에 액세스할 때 자동으로 Google 서비스 계정으로 인증됩니다.

Cloud API에 액세스하도록 Google 서비스 계정을 승인하는 방법은 서비스 계정 이해를 참조하세요.

용어

이 문서는 Kubernetes 서비스 계정(KSA)과 Google 서비스 계정 (GSA)을 구분합니다. KSA는 Kubernetes 리소스이며 GSA는 Google Cloud Platform에만 해당됩니다. 다른 GCP 문서에서는 GSA를 '서비스 계정'으로 지칭합니다.

클러스터 간 ID

GSA와 KSA 간의 관계는 프로젝트와 관련된 ID 네임스페이스로 정의됩니다. 이름, 네임스페이스 이름, ID 네임스페이스를 공유하는 모든 Kubernetes 서비스 계정은 GSA에 대한 액세스를 공유합니다. 여러 클러스터에 동일한 ID가 포함되는 경우 유용할 수 있지만 Kubernetes 서비스 계정 이름과 네임스페이스를 신중하게 관리하지 않으면 위험할 수 있습니다.

예를 들어 다음 명령어는 기본 서비스 계정과 네임스페이스를 사용하고 클러스터에 워크로드 아이덴티티가 사용 설정된 프로젝트의 모든 클러스터에 있는 모든 Kubernetes 워크로드에 동일한 액세스 권한을 부여합니다. 클러스터가 권한을 공유하지 못하도록 하려면 클러스터가 별도의 프로젝트에 있거나 고유한 Kubernetes 네임스페이스 이름을 사용해야 합니다. 구체적인 예를 들어 느슨한 'dev' 클러스터와 엄격한 'prod' 클러스터가 있는 사용자는 별도의 ID 네임스페이스를 얻기 위해 이러한 클러스터를 별도의 프로젝트로 분리하는 것을 고려해야 합니다.

gcloud iam service-accounts add-iam-policy-binding \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:[PROJECT_ID].svc.id.goog[default/default]" \
  [GSA_NAME]@[PROJECT_ID].iam.gserviceaccount.com

제한사항

  • 워크로드 아이덴티티는 GKE 버전 1.12 이상을 실행하는 클러스터에서 사용할 수 있습니다.

  • 워크로드 아이덴티티는 메타데이터 숨김을 사용해야 할 필요성을 대체하며, 따라서 두 접근 방법은 상호 호환되지 않습니다. 메타데이터 숨김으로 보호되는 민감한 메타데이터는 워크로드 아이덴티티로도 보호됩니다.

  • 워크로드 아이덴티티를 사용 설정하면 Compute Engine 기본 서비스 계정을 더 이상 사용할 수 없습니다. 자세한 내용은 아래 대안 섹션을 참조하세요.

  • 워크로드 아이덴티티는 호스트 네트워크에서 실행 중인 Pod와 함께 사용할 수 없습니다.

  • Stackdriver 및 Heapster와 같은 GKE 인프라 Pod는 계속 노드의 서비스 계정을 사용합니다.

시작하기 전에

이 작업을 준비하려면 다음 단계를 완료하세요.

  • Google Kubernetes Engine API가 사용 설정되었는지 확인합니다.
  • Google Kubernetes Engine API 사용 설정
  • Cloud SDK가 설치되었는지 확인합니다.
  • 기본 프로젝트 ID를 설정합니다.
    gcloud config set project [PROJECT_ID]
  • 영역 클러스터를 사용하는 경우 기본 컴퓨팅 영역을 설정합니다.
    gcloud config set compute/zone [COMPUTE_ZONE]
  • 리전 클러스터를 사용하는 경우 기본 컴퓨팅 리전을 설정합니다.
    gcloud config set compute/region [COMPUTE_REGION]
  • gcloud를 최신 버전으로 업데이트합니다.
    gcloud components update

새 클러스터에서 워크로드 아이덴티티 사용 설정

이 섹션에서는 워크로드 아이덴티티가 사용 설정된 클러스터를 만들고 Google 서비스 계정(GSA) ID로 Pod를 시작하는 방법을 설명합니다.

  1. IAM Credentials API를 사용 설정했는지 확인합니다.

    IAM Credentials API 사용 설정

  2. [CLUSTER_NAME]을 사용자 클러스터 이름으로 바꾸고 [PROJECT_ID]를 사용자 GCP 프로젝트 이름으로 바꾸어 워크로드 아이덴티티가 사용 설정된 클러스터를 만듭니다.

    gcloud beta container clusters create [CLUSTER_NAME] \
      --cluster-version=1.12 \
      --identity-namespace=[PROJECT_ID].svc.id.goog
    

    클러스터를 만드는 데는 몇 분 정도 걸립니다.

    이 작업에는 프로젝트에 대한 container.clusters.create 권한이 필요합니다.

    최소 권한 원칙에 따라 권한이 낮은 역할로 나머지 단계를 수행합니다. 각 단계에는 필요한 권한이 나와 있습니다.

  3. 클러스터와 통신하도록 kubectl을 구성합니다.

    gcloud container clusters get-credentials [CLUSTER_NAME]
    

    여기서 [CLUSTER_NAME]은 이전 단계에서 생성한 클러스터의 이름입니다.

    이 작업에는 프로젝트에 대한 container.clusters.get 권한이 필요합니다.

  4. [GSA_NAME]을 서비스 계정에 대해 선택한 이름으로 바꾸어 Google 서비스 계정을 만듭니다. 기존 서비스 계정이 있는 경우 새 서비스 계정을 만드는 대신 해당 계정을 사용할 수 있습니다.

    gcloud iam service-accounts create [GSA_NAME]
    

    이 작업에는 프로젝트에 대한 iam.serviceAccounts.create 권한이 필요합니다.

  5. 다른 대부분의 리소스와 마찬가지로 Kubernetes 서비스 계정은 네임스페이스에 위치합니다. Kubernetes 서비스 계정에 사용할 네임스페이스를 만듭니다.

    kubectl create namespace [K8S_NAMESPACE]
    

    이 작업을 수행하려면 클러스터 내에서 네임스페이스 RBAC 만들기 권한이 필요합니다.

  6. Kubernetes 서비스 계정을 만듭니다. --namespace 옵션에 이전 단계에서 만든 네임스페이스를 사용합니다. [KSA_NAME]을 서비스 계정에 사용하려는 이름으로 바꿉니다.

    kubectl create serviceaccount \
     --namespace [K8S_NAMESPACE] \
     [KSA_NAME]
    

    이 작업에는 네임스페이스 내에서 serviceaccounts RBAC 만들기 권한이 필요합니다.

    또는 기본 네임스페이스를 사용하거나 아무 네임스페이스의 기본 Kubernetes 서비스 계정을 사용할 수 있습니다.

  7. 두 계정 사이에 Cloud IAM 정책 바인딩을 만들어 Kubernetes 서비스 계정이 Google 서비스 계정을 사용하도록 허용합니다. 이 바인딩은 Kubernetes 서비스 계정이 Google 서비스 계정으로 작동하도록 허용합니다.

    gcloud iam service-accounts add-iam-policy-binding \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:[PROJECT_ID].svc.id.goog[[K8S_NAMESPACE]/[KSA_NAME]]" \
      [GSA_NAME]@[PROJECT_ID].iam.gserviceaccount.com
    

    이 작업을 수행하려면 Google 서비스 계정에 대한 iam.serviceAccounts.setIamPolicy 권한이 필요합니다.

  8. Google 서비스 계정의 이메일 주소를 사용하여 Kubernetes 서비스 계정에 iam.gke.io/gcp-service-account=[GSA_NAME]@[PROJECT_ID] 주석을 추가합니다.

    kubectl annotate serviceaccount \
      --namespace [K8S_NAMESPACE] \
      [KSA_NAME] \
      iam.gke.io/gcp-service-account=[GSA_NAME]@[PROJECT_ID].iam.gserviceaccount.com
    

    이 작업을 수행하려면 Kubernetes 서비스 계정에 대한 RBAC 수정 권한이 필요합니다.

  9. cloud-sdk 컨테이너 이미지를 실행하는 Kubernetes 서비스 계정으로 Pod를 만들고 대화형 세션으로 연결하여 서비스 계정이 올바르게 구성되었는지 확인합니다.

    kubectl run -it \
      --generator=run-pod/v1 \
      --image google/cloud-sdk \
      --serviceaccount [KSA_NAME] \
      --namespace [K8S_NAMESPACE] \
      workload-identity-test
    

    google/cloud-sdk 이미지에는 Google Cloud Platform API를 편리하게 사용할 수 있는 gcloud 명령줄 도구가 포함됩니다. 이미지를 다운로드하는 데 다소 시간이 걸릴 수 있습니다.

    이 작업을 수행하려면 네임스페이스 내에서 Pod RBAC 만들기 권한이 필요합니다.

    이제 생성된 Pod 내에서 대화형 셸에 연결되었습니다. 다음 명령어를 실행합니다.

    gcloud auth list
    

    서비스 계정이 올바르게 구성되었다면 Google 서비스 계정 이메일 주소가 유일한 활성 ID로 표시됩니다. 이는 기본적으로 Pod가 Google Cloud API를 호출할 때 Google 서비스 계정의 권한을 사용함을 보여줍니다.

삭제

  1. Google 서비스 계정에 대한 액세스 권한 취소:

    gcloud iam service-accounts remove-iam-policy-binding \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:[PROJECT_ID].svc.id.goog[[K8S_NAMESPACE]/[KSA_NAME]]" \
      [GSA_NAME]@[PROJECT_ID].iam.gserviceaccount.com
    

    이 작업을 수행하려면 서비스 계정에 대한 iam.serviceAccounts.setIamPolicy 권한이 필요합니다.

    캐시된 토큰이 만료되기까지 최대 30분이 걸릴 수 있습니다. 다음 명령어로 캐시된 토큰이 만료되었는지 여부를 확인할 수 있습니다.

    gcloud auth list
    

    해당 명령어의 출력에 더 이상 [GSA_NAME]@[PROJECT_ID].iam.gserviceaccount.com이 포함되지 않는 경우 캐시된 토큰이 만료된 것입니다.

  2. 클러스터에서 워크로드 아이덴티티를 사용 중지:

    gcloud beta container clusters update [CLUSTER_NAME] \
      --disable-workload-identity
    

    이 작업에는 클러스터에 대한 container.clusters.update 권한이 필요합니다.

기존 클러스터에서 워크로드 아이덴티티 사용 설정

  1. 워크로드 아이덴티티를 사용 설정하도록 클러스터를 수정합니다. 기존 노드 풀은 영향을 받지 않습니다. 새 노드 풀은 --workload-metadata-from-node=GKE_METADATA_SERVER로 기본 설정됩니다.

    gcloud beta container clusters update [CLUSTER_NAME] \
      --identity-namespace=[PROJECT_ID].svc.id.goog
    

이 작업에는 클러스터에 대한 container.clusters.update 권한이 필요합니다.

워크로드를 워크로드 아이덴티티로 마이그레이션

환경에 적합한 마이그레이션 전략을 선택합니다. 노드 풀을 제자리에서 마이그레이션하거나 워크로드 아이덴티티가 사용 설정된 새 노드 풀을 만들 수 있습니다. 이 기능과 호환되도록 애플리케이션을 수정해야 하는 경우 새 노드 풀을 만드는 것이 좋습니다.

옵션 1: 노드 풀 수정

기존 노드 풀을 수정하여 GKE_METADATA_SERVER를 사용 설정합니다. 이 업데이트는 클러스터에서 워크로드 아이덴티티가 사용 설정된 경우에만 성공합니다. 노드 풀에 배포된 워크로드에 대해 즉시 워크로드 아이덴티티가 사용 설정됩니다.

gcloud beta container node-pools update [NODEPOOL_NAME] \
  --cluster=[CLUSTER_NAME] \
  --workload-metadata-from-node=GKE_METADATA_SERVER

이 작업에는 프로젝트에 대한 container.nodes.update 권한이 필요합니다.

옵션 2: 워크로드 아이덴티티로 노드 풀 만들기

워크로드 아이덴티티가 사용 설정된 클러스터에 노드 풀을 추가하고 해당 풀로 워크로드를 수동으로 마이그레이션합니다. 이 작업은 클러스터에서 워크로드 아이덴티티가 사용 설정된 경우에만 성공합니다.

gcloud beta container node-pools create [NODEPOOL_NAME] \
  --cluster=[CLUSTER_NAME] \
  --workload-metadata-from-node=GKE_METADATA_SERVER

클러스터에 워크로드 아이덴티티가 사용 설정된 경우 --workload-metadata-from-node=EXPOSED 또는 --workload-metadata-from-node=SECURE를 명시적으로 지정하여 특정 노드 풀에서 선택적으로 사용 중지할 수 있습니다. 자세한 내용은 클러스터 메타데이터 보호를 참조하세요.

gcloud beta container node-pools create [NODEPOOL_NAME] \
  --cluster=[CLUSTER_NAME] \
  --workload-metadata-from-node=SECURE

이 작업에는 프로젝트에 대한 container.nodes.create 권한이 필요합니다.

삭제

  1. 기존 노드 풀을 수정하여 워크로드 아이덴티티를 사용 중지합니다.

    gcloud beta container node-pools update [NODEPOOL_NAME] \
      --cluster=[CLUSTER_NAME] \
      --workload-metadata-from-node=EXPOSED
    

    이 작업에는 프로젝트에 대한 container.nodes.update 권한이 필요합니다.

  2. 워크로드 아이덴티티를 사용 중지하도록 클러스터를 수정합니다. 기존 노드 풀은 영향을 받지 않습니다(단, 노드 풀에서 GKE_METADATA_SERVER를 사용 중인 경우 수정이 차단됨). 워크로드 아이덴티티를 사용 중지한 후 생성된 노드 풀의 경우 노드 풀에서 실행되는 Pod는 노드의 기본 Compute Engine 메타데이터 서버에 액세스할 수 있습니다.

    gcloud beta container clusters update [CLUSTER_NAME] \
      --disable-workload-identity
    

    이 작업에는 클러스터에 대한 container.clusters.update 권한이 필요합니다.

대안

GKE에서 Cloud API에 액세스하는 두 가지 대체 방법이 있습니다. 이러한 대체 접근 방법에는 타협이 필요하므로 워크로드 아이덴티티가 출시된 지금은 더 이상 권장되지 않습니다.

  1. 서비스 계정 키를 내보내 Kubernetes 보안 비밀로 저장합니다. Google 서비스 계정 키는 10년 후에 만료되며 수동으로 순환됩니다. 보안 침해가 감지되지 않을 경우 침해의 범위가 확대될 가능성이 있습니다.

  2. 노드에서 Compute Engine 기본 서비스 계정을 사용합니다. Compute Engine 기본 서비스 계정은 해당 노드에 배포된 모든 워크로드에서 공유됩니다. 이로 인해 권한이 과도하게 프로비저닝될 수 있습니다.

다음 단계

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

Kubernetes Engine 문서