18.5. STS での手動モードの使用

STS での手動モードは、Amazon Web Services (AWS) については テクノロジープレビュー として利用できます。

重要

AWS Secure Token Service (STS) のサポートはテクノロジープレビュー機能としてのみご利用いただけます。テクノロジープレビュー機能は Red Hat の実稼働環境でのサービスレベルアグリーメント (SLA) ではサポートされていないため、Red Hat では実稼働環境での使用を推奨していません。Red Hat は実稼働環境でこれらを使用することを推奨していません。テクノロジープレビューの機能は、最新の製品機能をいち早く提供して、開発段階で機能のテストを行いフィードバックを提供していただくことを目的としています。

Red Hat のテクノロジープレビュー機能のサポート範囲に関する詳細は、テクノロジープレビュー機能のサポート範囲 を参照してください。

注記

このクレデンシャルストラテジーは、新しい OpenShift Container Platform クラスターでのみサポートされており、インストール中に設定する必要があります。この機能を使用するために、既存のクラスターが別のクレデンシャルストラテジーを使用するように再設定することはできません。

STS での手動モードでは、個別の OpenShift Container Platform クラスターコンポーネントは AWS Secure Token Service (STS) を使用して、短期的かつ権限が制限されたセキュリティー認証情報を提供する IAM ロールをコンポーネントに割り当てます。これらの認証情報は、AWS API 呼び出しを行う各コンポーネントに固有の IAM ロールに関連付けられます。

新規および更新された認証情報の要求の自動化は、適切に設定された AWS IAM OpenID Connect (OIDC) アイデンティティープロバイダーを AWS IAM ロールと組み合わせて使用して実行されます。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
コンポーネントの namespace。
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
コンポーネントの namespace。
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. S3 バケットを作成し、OIDC 設定を保持します。

    $ 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) アイデンティティープロバイダーがこれらのファイルを読み取ることを許可します。

    $ 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 アイデンティティープロバイダーを作成します。

    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. アイデンティティープロバイダーを作成します。

      $ aws iam create-open-id-connect-provider --url $OPENID_BUCKET_URL --thumbprint-list $BUCKET_FINGERPRINT --client-id-list openshift sts.amazonaws.com
    4. 返される、新規作成されたアイデンティティープロバイダーの ARN を保持します。この ARN は後に <aws_iam_openid_arn> として参照されます。
  9. IAM ロールを生成します。

    1. このリリースイメージ内で、デプロイするクラウドをターゲットとする CredentialsRequest CR をすべて特定します。

      $ 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 について、以前に作成した IAM アイデンティティープロバイダーを使用して Web identity の IAM ロールを作成し、必要なパーミッションを付与し、以前に作成したアイデンティティープロバイダーを信頼する信頼関係を確立します。

      たとえば、0000_30_machine-api-operator_00_credentials-request.yamlCredentialsRequest CR の openshift-machine-api-operator は、以下のようにクラスター用に作成された OIDC プロバイダーからのアイデンティティーを許可する 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> は、返される、新規に作成されたアイデンティティープロバイダーの 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 ロールについて、IAM ポリシーを対応する CredentialsRequest オブジェクトからの必要なパーミッションを反映するロールに割り当てます。

    たとえば、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 に示されるターゲット namespace とターゲット名のあるシークレットを作成し、それぞれのコンポーネントについて以前に作成された 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 ロールを持つことを確認します。

    Image Registry Operator を使用したコマンドの例

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

    出力には、コンポーネントによって使用されるロールおよび Web アイデンティティートークンが表示され、以下のように表示されるはずです。

    Image Registry 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