AWS에 워크로드 아이덴티티 사용

워크로드 아이덴티티를 사용하면 클러스터의 애플리케이션마다 고유하고 세분화된 ID와 승인을 할당할 수 있습니다. 워크로드 아이덴티티는 AWS용 GKE 내에서 실행되는 애플리케이션이 AWS 및 Google Cloud 서비스에 액세스하는 데 권장되는 방법입니다. 자세한 내용은 워크로드 아이덴티티를 참조하세요.

이 주제에서는 OIDC 제공업체를 만들고 서비스 계정을 프로비저닝하고 워크로드 아이덴티티를 사용하여 샘플 워크로드를 테스트하는 방법을 설명합니다.

클러스터의 AWS IAM OIDC 제공업체 만들기

클러스터에 워크로드 아이덴티티를 사용하려면 먼저 클러스터를 참조하는 AWS IAM OIDC 제공업체를 만듭니다. 클러스터에 IAM OIDC 제공업체가 이미 있으면 이 섹션을 건너뛰어도 됩니다.

제공업체를 만들려면 다음 단계를 수행합니다.

  1. 클러스터의 OIDC 발급자 URI를 확인합니다.

    gcloud container aws clusters describe CLUSTER_NAME \
         --location=GOOGLE_CLOUD_LOCATION \
         --format='value(workloadIdentityConfig.issuerUri)'
    

    다음을 바꿉니다.

    • CLUSTER_NAME: 클러스터 이름입니다.
    • GOOGLE_CLOUD_LOCATION: Google Cloud 관리 리전에 정의된 대로 이 노드 풀이 관리되는 Google Cloud 위치의 이름입니다.

    출력에는 클러스터의 OIDC 발급자 URI가 포함됩니다. 다음 단계를 위해 이 값을 저장합니다.

  2. 그런 후 다음 명령어를 사용해서 클러스터를 참조하는 AWS IAM OIDC 제공업체를 만듭니다.

    aws iam create-open-id-connect-provider \
        --url ISSUER_URI \
        --client-id-list sts.amazonaws.com \
        --thumbprint-list 08745487e891c19e3078c1f2a07e452950ef36f6
    

    ISSUER_URI를 이전 단계의 발급자 URI로 바꿉니다.

    발급자 URI를 제공하는 Google Cloud 서비스의 지문은 항상 08745487e891c19e3078c1f2a07e452950ef36f6입니다.

연결된 IAM 정책으로 AWS IAM 역할 구성

AWS IAM 역할을 구성하고 여기에 정책을 연결하려면 다음 단계를 따르세요.

  1. 발급자 URI에서 https:// 프리픽스를 삭제하여 발급자 호스트를 확인합니다. 예를 들어 URI가 https://example.com이면 호스트가 example.com입니다. 이 값을 저장합니다. 서비스 계정의 고유 ID 값을 적어둡니다.

  2. 다음을 실행하여 제공업체의 Amazon 리소스 이름(ARN)을 확인합니다.

    aws iam list-open-id-connect-providers --output=text \
        --query 'OpenIDConnectProviderList[?ends_with(Arn, `ISSUER_HOST`) == `true`].Arn'
    

    ISSUER_HOST를 클러스터에 대한 발급자 URI의 호스트 이름으로 바꿉니다.

  3. 그런 후 Kubernetes 서비스 계정에 OIDC 사용자 인증 정보를 제공하도록 신뢰 정책을 만듭니다. 다음 콘텐츠로 trust-policy.json라는 파일을 만듭니다.

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "PROVIDER_ARN"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "ISSUER_HOST:sub": "system:serviceaccount:NAMESPACE:KSA_NAME"
            }
          }
        }
      ]
    }
    

    다음을 바꿉니다.

    • PROVIDER_ARN: 클러스터의 IAM OIDC 제공업체의 ARN입니다.
    • ISSUER_HOST: 클러스터에 대한 발급자 URI의 호스트 이름입니다.
    • NAMESPACE: 애플리케이션이 실행되는 Kubernetes 네임스페이스입니다.
    • KSA_NAME: 애플리케이션에 사용할 Kubernetes 서비스 계정(KSA)입니다.
  4. AWS IAM 역할을 만듭니다.

    aws iam create-role --role-name=AWS_ROLE_NAME \
        --assume-role-policy-document file://trust-policy.json
    

    AWS_ROLE_NAME을 애플리케이션의 AWS IAM 역할 이름으로 바꿉니다.

  5. AWS IAM 정책을 역할에 연결합니다.

    aws iam attach-role-policy --role-name=AWS_ROLE_NAME \
        --policy-arn=AWS_POLICY_ARN
    

    다음을 바꿉니다.

    • AWS_ROLE_NAME: 애플리케이션의 AWS IAM 역할 이름입니다.

    예를 들어 ec2-readonly라는 역할을 만들려면 arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess 정책을 사용해서 다음 명령어를 실행합니다.

    aws iam attach-role-policy --role-name=ec2-readonly \
        --policy-arn=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
    

샘플 애플리케이션 배포

워크로드 아이덴티티를 테스트하려면 다음 단계에 따라 샘플 애플리케이션을 배포합니다.

  1. 역할의 ARN을 확인합니다.

    aws iam get-role --role-name=AWS_ROLE_NAME --query 'Role.Arn'
    

    AWS_ROLE_NAME을 바꿉니다.

  2. Kubernetes 네임스페이스, KSA 및 포드에 대해 매니페스트를 만듭니다. 다음 매니페스트를 workload-identity-test.yaml이라는 파일에 복사합니다.

    apiVersion: v1
    kind: Namespace
    metadata:
      name: NAMESPACE
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: KSA_NAME
      namespace: NAMESPACE
    automountServiceAccountToken: false
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: aws-cli-example
      namespace: NAMESPACE
    spec:
      serviceAccount: KSA_NAME
      containers:
      - name: aws-cli
        image: amazon/aws-cli:latest
        command:
        - /bin/bash
        - -c
        - "set -eu -o pipefail; while true; do aws ec2 describe-availability-zones; sleep 5; done"
        env:
        - name: AWS_ROLE_ARN
          value: AWS_ROLE_ARN
        - name: AWS_WEB_IDENTITY_TOKEN_FILE
          value: /var/run/secrets/aws-iam-token/serviceaccount/token
        - name: AWS_REGION
          value: AWS_REGION
        volumeMounts:
        - mountPath: /var/run/secrets/aws-iam-token/serviceaccount
          name: aws-iam-token
          readOnly: true
      volumes:
      - name: aws-iam-token
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              audience: sts.amazonaws.com
              expirationSeconds: 86400
              path: token
    

    다음을 바꿉니다.

    • NAMESPACE
    • KSA_NAME
    • AWS_ROLE_ARN: 애플리케이션에 대한 AWS IAM 역할의 ARN입니다.
    • AWS_REGION: 클러스터의 AWS 리전입니다.
  3. 매니페스트를 적용합니다.

    kubectl apply -f workload-identity-test.yaml
    

    포드가 시작되도록 몇 분 기다린 후 다음 섹션을 진행합니다.

샘플 애플리케이션 작동 확인

샘플 애플리케이션이 EC2 API에 액세스할 수 있는지 확인하려면 포드 로그를 확인합니다.

kubectl logs -f aws-cli-example -n NAMESPACE

포드가 EC2 API에 액세스할 수 있으면 출력에 EC2 가용성 영역에 대한 정보가 포함되고 다음과 비슷하게 표시됩니다.

-------------------------------------------------
|           DescribeAvailabilityZones           |
+-----------------------------------------------+
||              AvailabilityZones              ||
|+---------------------+-----------------------+|
||  GroupName          |  us-west-2            ||
||  NetworkBorderGroup |  us-west-2            ||
||  OptInStatus        |  opt-in-not-required  ||
||  RegionName         |  us-west-2            ||
||  State              |  available            ||
||  ZoneId             |  usw2-az1             ||
||  ZoneName           |  us-west-2a           ||
|+---------------------+-----------------------+|
||              AvailabilityZones              ||
|+---------------------+-----------------------+|
||  GroupName          |  us-west-2            ||
||  NetworkBorderGroup |  us-west-2            ||
||  OptInStatus        |  opt-in-not-required  ||
||  RegionName         |  us-west-2            ||
||  State              |  available            ||
||  ZoneId             |  usw2-az2             ||
||  ZoneName           |  us-west-2b           ||
|+---------------------+-----------------------+|
||              AvailabilityZones              ||
|+---------------------+-----------------------+|
||  GroupName          |  us-west-2            ||
||  NetworkBorderGroup |  us-west-2            ||
||  OptInStatus        |  opt-in-not-required  ||
||  RegionName         |  us-west-2            ||
||  State              |  available            ||
||  ZoneId             |  usw2-az3             ||
||  ZoneName           |  us-west-2c           ||
|+---------------------+-----------------------+|
||              AvailabilityZones              ||
|+---------------------+-----------------------+|
||  GroupName          |  us-west-2            ||
||  NetworkBorderGroup |  us-west-2            ||
||  OptInStatus        |  opt-in-not-required  ||
||  RegionName         |  us-west-2            ||
||  State              |  available            ||
||  ZoneId             |  usw2-az4             ||
||  ZoneName           |  us-west-2d           ||
|+---------------------+-----------------------+|

삭제

이 샘플 애플리케이션을 삭제하려면 다음 단계를 따르세요.

  1. 클러스터에서 샘플 애플리케이션의 매니페스트를 삭제합니다.

    kubectl delete -f workload-identity-test.yaml
    
  2. 역할에서 AWS IAM 정책을 분리합니다.

    aws iam detach-role-policy --role-name AWS_ROLE_NAME \
        --policy-arn arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
    

    AWS_ROLE_NAME을 애플리케이션의 AWS IAM 역할 이름으로 바꿉니다.

  3. AWS IAM 역할을 삭제합니다.

    aws iam delete-role --role-name AWS_ROLE_NAME
    

    AWS_ROLE_NAME을 애플리케이션의 AWS IAM 역할 이름으로 바꿉니다.

  4. AWS IAM OIDC 제공업체를 삭제합니다.

    aws iam delete-open-id-connect-provider --open-id-connect-provider-arn PROVIDER_ARN
    

    PROVIDER_ARN을 클러스터에 대한 IAM OIDC 제공업체의 ARN으로 바꿉니다.

다음 단계