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>
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
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 リソースを手動で作成する必要があります。
手順
ServiceAccount
オブジェクトに署名するためにプライベートキーを生成します。$ openssl genrsa -out sa-signer 4096
ServiceAccount
オブジェクトのパブリックキーを生成します。$ openssl rsa -in sa-signer -pubout -out sa-signer.pub
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
パラメーターを指定しません。S3 バケット URL を保持します。
OPENID_BUCKET_URL="https://<oidc_bucket_name>.s3.<aws_region>.amazonaws.com"
OIDC 設定をビルドします。
以下の情報が含まれる
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 でエンコードされた出力を変更します。
以下の情報が含まれる
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" ] }
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 バケットです。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
AWS IAM OIDC アイデンティティープロバイダーを作成します。
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}'
チェーンのルートで証明書のフィンガープリントを計算します。
$ export BUCKET_FINGERPRINT=$(openssl x509 -in cert<number>.pem -fingerprint -noout | sed -e 's/.*Fingerprint=//' -e 's/://g')
ここで、
<number>
は保存されたファイルの最も大きな数になります。たとえば、保存したファイル内で2
が最大値であれば、cert2.pem
を使用します。アイデンティティープロバイダーを作成します。
$ aws iam create-open-id-connect-provider --url $OPENID_BUCKET_URL --thumbprint-list $BUCKET_FINGERPRINT --client-id-list openshift sts.amazonaws.com
-
返される、新規作成されたアイデンティティープロバイダーの ARN を保持します。この ARN は後に
<aws_iam_openid_arn>
として参照されます。
IAM ロールを生成します。
このリリースイメージ内で、デプロイするクラウドをターゲットとする
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 のバージョンに対応する番号になります。それぞれの
CredentialsRequest
CR について、以前に作成した IAM アイデンティティープロバイダーを使用してWeb identity
の IAM ロールを作成し、必要なパーミッションを付与し、以前に作成したアイデンティティープロバイダーを信頼する信頼関係を確立します。たとえば、
0000_30_machine-api-operator_00_credentials-request.yaml
のCredentialsRequest
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 です。特定のクラスターの
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" ] } }
各 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 } } } ] } }
OpenShift Container Platform インストーラーを実行する準備をします。
install-config.yaml
ファイルを作成します。$ ./openshift-install create install-config
手動モードで CCO を使用してインストールするようにクラスターを設定します。
$ echo "credentialsMode: Manual" >> install-config.yaml
インストールマニフェストを作成します。
$ ./openshift-install create manifests
tls
ディレクトリーを作成し、以前に生成されたプライベートキーをここにコピーします。注記ターゲットファイル名は
./tls/bound-service-account-signing-key.key
である必要があります。$ mkdir tls ; cp <path_to_service_account_signer> ./tls/bound-service-account-signing-key.key
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
リリースイメージから抽出される各
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. インストールの検証
- OpenShift Container Platform クラスターに接続します。
クラスターに
root
認証情報がないことを確認します。$ oc get secrets -n kube-system aws-creds
出力は以下のようになります。
Error from server (NotFound): secrets "aws-creds" not found
コンポーネントが、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