18.5. STS를 사용하는 수동 모드 사용

STS를 사용하는 수동 모드는 AWS(Amazon Web Services)용 기술 프리뷰로 사용할 수 있습니다.

중요

AWS STS(Secure Token Service)에 대한 지원은 기술 프리뷰 기능 전용입니다. Technology Preview 기능은 Red Hat 프로덕션 서비스 수준 계약(SLA)에서 지원되지 않으며 기능적으로 완전하지 않을 수 있습니다. 따라서 프로덕션 환경에서 사용하는 것은 권장하지 않습니다. 이러한 기능을 사용하면 향후 제품 기능을 조기에 이용할 수 있어 개발 과정에서 고객이 기능을 테스트하고 피드백을 제공할 수 있습니다.

Red Hat 기술 프리뷰 기능의 지원 범위에 대한 자세한 내용은 https://access.redhat.com/support/offerings/techpreview/를 참조하십시오.

참고

이 인증 정보 전략은 새 OpenShift Container Platform 클러스터에 대해서만 지원되며 설치 중에 구성해야 합니다. 이 기능을 사용하기 위해 다른 인증 정보 전략을 사용하는 기존 클러스터를 재구성할 수 없습니다.

STS를 사용하는 수동 모드에서 개별 OpenShift Container Platform 클러스터 구성 요소는 AWS STS(Secure Token Service)를 사용하여 단기적으로 제한된 권한 보안 인증 정보를 제공하는 구성 요소 IAM 역할을 할당합니다. 이러한 인증 정보는 AWS API 호출을 수행하는 각 구성 요소에 특정적인 IAM 역할과 연결됩니다.

새로운 인증 정보 및 새로고침된 인증 정보에 대한 요청은 AWS IAM 역할과 함께 적절하게 구성된 AWS IAM OIDC(OpenID Connect) ID 공급자를 사용하여 자동화됩니다. OpenShift Container Platform은 AWS IAM에서 신뢰하는 서비스 계정 토큰에 서명하고 Pod에 프로젝션하고 인증에 사용할 수 있습니다. 토큰은 1시간 후에 새로 고쳐집니다.

그림 18.1. STS 인증 흐름

STS를 사용하여 수동 모드를 사용하면 개별 OpenShift Container Platform 구성 요소에 제공되는 AWS 인증 정보의 내용이 변경됩니다.

수명이 긴 인증 정보를 사용하는 AWS 시크릿 형식

apiVersion: v1
kind: Secret
metadata:
  namespace: <target-namespace> 1
  name: <target-secret-name> 2
data:
  aws_access_key_id: <base64-encoded-access-key-id>
  aws_secret_access_key: <base64-encoded-secret-access-key>

1
구성 요소의 네임스페이스입니다.
2
구성 요소 시크릿의 이름입니다.

STS를 사용하는 AWS 시크릿 형식

apiVersion: v1
kind: Secret
metadata:
  namespace: <target-namespace> 1
  name: <target-secret-name> 2
stringData:
  credentials: |-
    [default]
    role_name: <operator-role-name> 3
    web_identity_token_file: <path-to-token> 4

1
구성 요소의 네임스페이스입니다.
2
구성 요소 시크릿의 이름입니다.
3
구성 요소의 IAM 역할입니다.
4
Pod 내의 서비스 계정 토큰 경로입니다. 관례상 이는 OpenShift Container Platform 구성 요소의 /var/run/secrets/openshift/serviceaccount/token입니다.

18.5.1. STS를 사용하여 수동 모드에 구성된 OpenShift Container Platform 클러스터 설치

OpenShift Container Platform 버전 4.7에서 STS를 사용하여 수동 모드에서 CCO를 사용하도록 구성된 클러스터를 설치하려면 다음을 수행합니다.

18.5.1.1. 수동으로 AWS 리소스 생성

STS를 사용하여 수동 모드에서 CCO를 사용하도록 구성된 OpenShift Container Platform 클러스터를 설치하려면 먼저 필요한 AWS 리소스를 수동으로 생성해야 합니다.

절차

  1. ServiceAccount 오브젝트에 서명할 개인 키를 생성합니다.

    $ openssl genrsa -out sa-signer 4096
  2. ServiceAccount 오브젝트 공개 키를 생성합니다.

    $ openssl rsa -in sa-signer -pubout -out sa-signer.pub
  3. OIDC 구성을 유지하기 위해 S3 버킷을 생성합니다.

    $ aws s3api create-bucket --bucket <oidc_bucket_name> --region <aws_region> --create-bucket-configuration LocationConstraint=<aws_region>
    참고

    <aws_region>의 값이 us-east-1인 경우 LocationConstraint 매개변수를 지정하지 마십시오.

  4. S3 버킷 URL을 유지합니다.

    OPENID_BUCKET_URL="https://<oidc_bucket_name>.s3.<aws_region>.amazonaws.com"
  5. OIDC 구성을 빌드합니다.

    1. 다음 정보가 포함된 keys.json이라는 파일을 생성합니다.

      {
          "keys": [
              {
                  "use": "sig",
                  "kty": "RSA",
                  "kid": "<public_signing_key_id>",
                  "alg": "RS256",
                  "n": "<public_signing_key_modulus>",
                  "e": "<public_signing_key_exponent>"
              }
          ]
      }

      다음과 같습니다.

      • <public_signing_key_id>는 다음을 사용하여 공개 키에서 생성됩니다.

        $ openssl rsa -in sa-signer.pub -pubin --outform DER | openssl dgst -binary -sha256 | openssl base64 | tr '/+' '_-' | tr -d '='

        이 명령은 공개 키를 DER 형식으로 변환하고, 바이너리 표현에서 SHA-256 체크섬을 수행하고, base64 인코딩으로 데이터를 인코딩한 다음 base64로 인코딩된 출력을 base64URL 인코딩으로 변경합니다.

      • <public_signing_key_modulus>는 다음을 사용하여 공개 키에서 생성됩니다.

        $ openssl rsa -pubin -in sa-signer.pub -modulus -noout | sed  -e 's/Modulus=//' | xxd -r -p | base64 -w0 | tr '/+' '_-' | tr -d '='

        이 명령은 공개 키의 모듈러스를 출력하고, 모듈러스의 16진수 표현을 추출하고, ASCII 16진수를 바이너리로 변환하고, base64 인코딩으로 데이터를 인코딩한 다음 base64로 인코딩된 출력을 base64URL 인코딩으로 변경합니다.

      • <public_signing_key_exponent>는 다음을 사용하여 공개 키에서 생성됩니다.

        $ printf "%016x" $(openssl rsa -pubin -in sa-signer.pub -noout -text | grep Exponent | awk '{ print $2 }') |  awk '{ sub(/(00)+/, "", $1); print $1 }' | xxd -r -p | base64 -w0 | tr '/+' '_-' | tr -d '='

        이 명령은 공개 키 진수의 10진수 표현을 추출하고, 필요에 따라 채워진 0을 사용하여 16진수로 출력하고, 선두 00 쌍을 제거하고, ASCII 16진수를 바이너리로 변환하고, base64 인코딩 데이터를 인코딩한 다음, URL에 사용할 수 있는 문자만 사용하도록 base64로 인코딩된 출력을 변경합니다.

    2. 다음 정보가 포함된 openid-configuration이라는 파일을 생성합니다.

      {
      	"issuer": "$OPENID_BUCKET_URL",
      	"jwks_uri": "${OPENID_BUCKET_URL}/keys.json",
          "response_types_supported": [
              "id_token"
          ],
          "subject_types_supported": [
              "public"
          ],
          "id_token_signing_alg_values_supported": [
              "RS256"
          ],
          "claims_supported": [
              "aud",
              "exp",
              "sub",
              "iat",
              "iss",
              "sub"
          ]
      }
  6. OIDC 구성을 업로드합니다.

    $ aws s3api put-object --bucket <oidc_bucket_name> --key keys.json --body ./keys.json
    $ aws s3api put-object --bucket <oidc_bucket_name> --key '.well-known/openid-configuration' --body ./openid-configuration

    여기서 <oidc_bucket_name>은 OIDC 구성을 유지하기 위해 생성된 S3 버킷입니다.

  7. AWS IAM OpenID Connect (OIDC) ID 공급자가 다음 파일을 읽도록 허용합니다.

    $ aws s3api put-object-acl --bucket <oidc_bucket_name> --key keys.json --acl public-read
    $ aws s3api put-object-acl --bucket <oidc_bucket_name> --key '.well-known/openid-configuration' --acl public-read
  8. AWS IAM OIDC ID 공급자를 생성합니다.

    1. OIDC 구성을 호스팅하는 서버에서 인증서 체인을 가져옵니다.

      $ echo | openssl s_client -servername $<oidc_bucket_name>.s3.$<aws_region>.amazonaws.com -connect $<oidc_bucket_name>.s3.$<aws_region>.amazonaws.com:443 -showcerts 2>/dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; out="cert"a".pem"; print >out}'
    2. 체인의 루트에서 인증서의 지문을 계산합니다.

      $ export BUCKET_FINGERPRINT=$(openssl x509 -in cert<number>.pem -fingerprint -noout | sed -e 's/.*Fingerprint=//' -e 's/://g')

      여기서 <number>는 저장된 파일에서 가장 높은 수입니다. 예를 들어 2가 저장된 파일에서 가장 높은 수인 경우 cert2.pem을 사용합니다.

    3. ID 공급자를 생성합니다.

      $ aws iam create-open-id-connect-provider --url $OPENID_BUCKET_URL --thumbprint-list $BUCKET_FINGERPRINT --client-id-list openshift sts.amazonaws.com
    4. 새로 생성된 ID 공급자의 반환된 ARN을 유지합니다. 이 ARN은 나중에 <aws_iam_openid_arn>이라고 합니다.
  9. IAM 역할을 생성합니다.

    1. 배포 중인 클라우드를 대상으로 하는 이 릴리스 이미지에서 모든 CredentialsRequest 오브젝트를 찾습니다.

      $ oc adm release extract quay.io/openshift-release-dev/ocp-release:4.<y>.<z>-x86_64 --credentials-requests --cloud=aws

      여기서 <y><z>는 설치 중인 OpenShift Container Platform 버전에 해당하는 번호입니다.

    2. CredentialsRequest CR에 대해 필요한 권한을 부여하고 이전에 생성된 ID 공급자를 신뢰하는 신뢰 관계를 설정하는 이전에 생성된 IAM ID 공급자를 사용하여 웹 ID 유형의 IAM 역할을 생성합니다.

      예를 들어 0000_30_machine-api-operator_00_credentials-request.yaml에서 openshift-machine-api-operator CredentialsRequest CR의 경우 다음과 같이 클러스터에 대해 생성된 OIDC 공급자의 ID를 허용하는 IAM 역할을 생성합니다.

      {
          "Role": {
              "Path": "/",
              "RoleName": "openshift-machine-api-aws-cloud-credentials",
              "RoleId": "ARSOMEROLEID",
              "Arn": "arn:aws:iam::123456789012:role/openshift-machine-api-aws-cloud-credentials",
              "CreateDate": "2021-01-06T15:54:13Z",
              "AssumeRolePolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [
                      {
                          "Effect": "Allow",
                          "Principal": {
                              "Federated": "<aws_iam_openid_arn>"
                          },
                          "Action": "sts:AssumeRoleWithWebIdentity",
                          "Condition": {
                              "StringEquals": {
                                  "<oidc_bucket_name>.s3.<aws_region>.amazonaws.com/$BUCKET_NAME:aud": "openshift"
                              }
                          }
                      }
                  ]
              },
              "Description": "OpenShift role for openshift-machine-api/aws-cloud-credentials",
              "MaxSessionDuration": 3600,
              "RoleLastUsed": {
                  "LastUsedDate": "2021-02-03T02:51:24Z",
                  "Region": "<aws_region>"
              }
          }
      }

      여기서 <aws_iam_openid_arn>은 새로 생성된 ID 공급자의 반환된 ARN입니다.

    3. 특정 클러스터 ServiceAccount 오브젝트만 해당 역할을 가정할 수 있게 역할을 추가로 제한하려면 .Role.AssumeRolePolicyDocument.Statement[].Condition 필드를 각 구성 요소의 특정 ServiceAccount 오브젝트로 업데이트하여 각 역할의 신뢰 관계를 수정하십시오.

      • 다음 조건을 갖도록 cluster-image-registry-operator 역할의 신뢰 관계를 수정합니다.

        "Condition": {
          "StringEquals": {
            "<oidc_bucket_name>.s3.<aws_region>.amazonaws.com:sub": [
              "system:serviceaccount:openshift-image-registry:registry",
              "system:serviceaccount:openshift-image-registry:cluster-image-registry-operator"
            ]
          }
        }
      • 다음 조건을 갖도록 openshift-ingress-operator의 신뢰 관계를 수정합니다.

        "Condition": {
          "StringEquals": {
            "<oidc_bucket_name>.s3.<aws_region>.amazonaws.com:sub": [
              "system:serviceaccount:openshift-ingress-operator:ingress-operator"
            ]
          }
        }
      • 다음 조건을 갖도록 openshift-cluster-csi-drivers의 신뢰 관계를 수정합니다.

        "Condition": {
          "StringEquals": {
            "<oidc_bucket_name>.s3.<aws_region>.amazonaws.com:sub": [
              "system:serviceaccount:openshift-cluster-csi-drivers:aws-ebs-csi-driver-operator",
              "system:serviceaccount:openshift-cluster-csi-drivers:aws-ebs-csi-driver-controller-sa"
            ]
          }
        }
      • 다음 조건을 갖도록 openshift-machine-api의 신뢰 관계를 수정합니다.

        "Condition": {
          "StringEquals": {
            "<oidc_bucket_name>.s3.<aws_region>.amazonaws.com:sub": [
              "system:serviceaccount:openshift-machine-api:machine-api-controllers"
            ]
          }
        }
  10. 각 IAM 역할에 대해 해당 CredentialsRequest 오브젝트에서 필요한 권한을 반영하는 역할에 IAM 정책을 연결합니다.

    예를 들어 openshift-machine-api의 경우 다음과 유사한 IAM 정책을 연결합니다.

    {
        "RoleName": "openshift-machine-api-aws-cloud-credentials",
        "PolicyName": "openshift-machine-api-aws-cloud-credentials",
        "PolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Action": [
                        "ec2:CreateTags",
                        "ec2:DescribeAvailabilityZones",
                        "ec2:DescribeDhcpOptions",
                        "ec2:DescribeImages",
                        "ec2:DescribeInstances",
                        "ec2:DescribeSecurityGroups",
                        "ec2:DescribeSubnets",
                        "ec2:DescribeVpcs",
                        "ec2:RunInstances",
                        "ec2:TerminateInstances",
                        "elasticloadbalancing:DescribeLoadBalancers",
                        "elasticloadbalancing:DescribeTargetGroups",
                        "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
                        "elasticloadbalancing:RegisterTargets",
                        "iam:PassRole",
                        "iam:CreateServiceLinkedRole"
                    ],
                    "Resource": "*"
                },
                {
                    "Effect": "Allow",
                    "Action": [
                        "kms:Decrypt",
                        "kms:Encrypt",
                        "kms:GenerateDataKey",
                        "kms:GenerateDataKeyWithoutPlainText",
                        "kms:DescribeKey"
                    ],
                    "Resource": "*"
                },
                {
                    "Effect": "Allow",
                    "Action": [
                        "kms:RevokeGrant",
                        "kms:CreateGrant",
                        "kms:ListGrants"
                    ],
                    "Resource": "*",
                    "Condition": {
                        "Bool": {
                            "kms:GrantIsForAWSResource": true
                        }
                    }
                }
            ]
        }
    }
  11. OpenShift Container Platform 설치 프로그램 실행을 준비합니다.

    1. install-config.yaml 파일을 생성합니다.

      $ ./openshift-install create install-config
    2. 수동 모드에서 CCO로 설치하도록 클러스터를 구성합니다.

      $ echo "credentialsMode: Manual" >> install-config.yaml
    3. 설치 매니페스트를 생성합니다.

      $ ./openshift-install create manifests
    4. tls 디렉터리를 생성하고 이전에 생성된 개인 키를 복사합니다.

      참고

      대상 파일 이름은 ./tls/bound-service-account-signing-key.key여야 합니다.

      $ mkdir tls ; cp <path_to_service_account_signer> ./tls/bound-service-account-signing-key.key
    5. cluster-authentication-02-config.yaml 파일 이름으로 사용자 지정 Authentication CR을 생성합니다.

      $ cat << EOF > manifests/cluster-authentication-02-config.yaml
      apiVersion: config.openshift.io/v1
      kind: Authentication
      metadata:
        name: cluster
      spec:
        serviceAccountIssuer: $OPENID_BUCKET_URL
      EOF
    6. 릴리스 이미지에서 추출된 각 CredentialsRequest CR에 대해 각 CredentialsRequest에 표시된 대상 네임스페이스와 대상 이름으로 시크릿을 생성하여 각 구성 요소에 대해 이전에 생성된 AWS IAM 역할 ARN을 대체합니다.

      openshift-machine-api 의 시크릿 매니페스트 예:

      $ cat manifests/openshift-machine-api-aws-cloud-credentials-credentials.yaml
      apiVersion: v1
      stringData:
        credentials: |-
          [default]
          role_arn = arn:aws:iam::123456789012:role/openshift-machine-api-aws-cloud-credentials
          web_identity_token_file = /var/run/secrets/openshift/serviceaccount/token
      kind: Secret
      metadata:
        name: aws-cloud-credentials
        namespace: openshift-machine-api
      type: Opaque

18.5.1.2. 설치 프로그램 실행

  • OpenShift Container Platform 설치 프로그램을 실행합니다.

    $ ./openshift-install create cluster

18.5.1.3. 설치 확인

  1. OpenShift Container Platform 클러스터에 연결합니다.
  2. 클러스터에 root 인증 정보가 없는지 확인합니다.

    $ oc get secrets -n kube-system aws-creds

    출력은 다음과 유사해야 합니다.

    Error from server (NotFound): secrets "aws-creds" not found
  3. 구성 요소가 CCO에서 생성한 인증 정보를 사용하는 대신 시크릿 매니페스트에 지정된 IAM 역할을 가정하는지 확인합니다.

    이미지 레지스트리 Operator가 있는 명령 예

    $ oc get secrets -n openshift-image-registry installer-cloud-credentials -o json | jq -r .data.credentials | base64 --decode

    출력에 구성 요소에서 사용하는 역할 및 웹 ID 토큰이 표시되고 다음과 유사해야 합니다.

    이미지 레지스트리 Operator가 있는 출력 예

    [default]
    role_arn = arn:aws:iam::123456789:role/openshift-image-registry-installer-cloud-credentials
    web_identity_token_file = /var/run/secrets/openshift/serviceaccount/token