ROSAでのAWS STSによるAmazon EFS/ECRの利用

OpenShift Advent Calendar 2024の12/17の記事です。

Red Hatの小島です。

Red Hat OpenShift Service on AWS(ROSA)ではセキュリティを考慮してAWS STS(Security Token Service)を利用したデプロイと運用を推奨しており、ROSA with HCPクラスターをデプロイする際は、AWS STSの利用を必須としています。本記事ではAWSユーザーから聞かれることの多いAmazon EFSとAmazon ECRについて、専用のOperatorからAWS STSの認証情報で利用する方法の概要をご紹介します。なお、ROSA環境からAWS STSを利用してAWSリソースにアクセスする仕組みの解説は下記のブログに記載されていますので、こちらも併せてご参照ください。

qiita.com

注: 本記事にあるECR Secret Operatorを利用する時、ROSA/OpenShiftのバージョン4.17系では4.17.7以降をご利用ください。

ECR Secret OperatorはROSA/OpenShift バージョン4.16系までの環境で機能します。ROSA/OpenShift バージョン4.17系の環境では機能しないのでご注意ください。

AWS Elastic File Service CSI Driver Operatorの利用

OpenShiftやROSAではAmazon EKSと同様に、Amazon EFSのContainer Storage Interface(CSI)ドライバーを使用して永続ボリュームをプロビジョニングできるようになっています。Amazon EFSのCSIドライバーを簡単に利用するためのOperatorが、OpenShiftのOperatorHubで「AWS Elastic File Service CSI Driver Operator」という名前で提供されています。このOperatorでインストールできるCSIドライバーによって、Amazon EFSの動的プロビジョニングと静的プロビジョニングが可能になります。

AWS側の準備

AWS Elastic File Service CSI Driver Operatorを利用するための前準備として、Amazon EFSを利用するためのAWS IAMロールとポリシーを最初に作成します。これについては、前述のブログで触れているccoctlを使う手順もありますが、ここではAWSのCLIやコンソールを使って作成することにします。

次のコマンドで、Amazon EFSを利用するためのIAMポリシーを作成します。

$ cat << EOF > efs-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "elasticfilesystem:DescribeAccessPoints",
        "elasticfilesystem:DescribeFileSystems",
        "elasticfilesystem:DescribeMountTargets",
        "elasticfilesystem:TagResource",
        "ec2:DescribeAvailabilityZones"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "elasticfilesystem:CreateAccessPoint"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "aws:RequestTag/efs.csi.aws.com/cluster": "true"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": "elasticfilesystem:DeleteAccessPoint",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/efs.csi.aws.com/cluster": "true"
        }
      }
    }
  ]
}
EOF

$ aws iam create-policy \
  --policy-name rosa-efs-csi-policy \
  --policy-document file://./efs-policy.json \
  --query 'Policy.Arn' --output text
arn:aws:iam::<AWS_ACCOUNT_ID>:policy/rosa-efs-csi-policy

IAMロールを作成して、先ほど作成したIAMポリシーを割り当てます。この時、ROSAクラスターで利用しているOpenID Connect (OIDC) IDプロバイダーのARNを指定します。このIAMロールによって、指定したOIDC IDプロバイダーを利用するROSAクラスターの特定のサービスアカウントがAWSリソースにアクセスするための、一時的な認証情報が自動的にリクエストされるようになります。

$ rosa list oidc-providers
I: Fetching OIDC providers
OIDC PROVIDER ARN                                                                            Cluster ID                        In Use
arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/oidc.op1.openshiftapps.com/289dfj5mirXXXXXX  2el3camm8eh4eq8p19vtcm9n0iujmggq  Yes

$ cat <<EOF > efs-trust.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/oidc.op1.openshiftapps.com/289dfj5mirXXXXXX"  
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.op1.openshiftapps.com/289dfj5mirXXXXXX:sub": [  
            "system:serviceaccount:openshift-cluster-csi-drivers:aws-efs-csi-driver-operator",
            "system:serviceaccount:openshift-cluster-csi-drivers:aws-efs-csi-driver-controller-sa"
          ]
        }
      }
    }
  ]
}
EOF

$ aws iam create-role \
  --role-name rosa-efs-csi-role \
  --assume-role-policy-document file://./efs-trust.json \
  --query "Role.Arn" --output text
arn:aws:iam::<AWS_ACCOUNT_ID>:role/rosa-efs-csi-role

$ aws iam attach-role-policy \
  --role-name rosa-efs-csi-role \
  --policy-arn arn:aws:iam::<AWS_ACCOUNT_ID>:policy/rosa-efs-csi-policy

続いて、ROSAクラスターと同じAWSリージョンにAmazon EFSのファイルシステムを作成します。Amazon EFSのコンソールにアクセスして、「ファイルシステムの作成」から「カスタマイズ」を選択します。

「ステップ1: ファイルシステムの作成」はデフォルトのパラメーターを全て利用します。ここでは、マルチAZ(デフォルト)とシングルAZのどちらのファイルシステムにするかを選択できますが、デフォルトのマルチAZのままにしておいて「ステップ2: ネットワークアクセス」に進みます。

「ステップ2: ネットワークアクセス」ではROSAクラスターが利用するVPCと、ワーカーノードが利用するプライベートサブネットIDを指定してマウントターゲットを作成します。この画像はROSAクラスターをシングルAZ構成で作成している時の例です。マルチAZ構成のROSAクラスターを利用する場合は、各AZでワーカーノードが利用するプライベートサブネットごとにマウントターゲットを追加していくことになります。例えば、3つのAZのワーカーノードを利用するROSAクラスターの場合は、3つのマウントターゲットを作成する必要があります。

セキュリティグループは、ROSAクラスターが利用しているものでなくても大丈夫です。VPCを作成した時にデフォルトで作成されるセキュリティグループなどを指定できます。「次へ」から「ステップ3: ファイルシステムポリシー」に進みます。

「ステップ3: ファイルシステムポリシーは」全てデフォルトのパラメーターのままにしておいて、「ステップ4」で確認したら「作成」をクリックして、ファイルシステムの作成を完了します。作成したファイルシステムのID(fs-XXXXX)は後で利用しますので、メモしておきます。

先ほどファイルシステムを作成した時に指定したセキュリティグループで、NFSを利用するためのTCP2049ポートを開けておきます。セキュリティグループの「インバウンドのルールを編集」画面で、「NFS」タイプとROSAクラスターのワーカーノードのCIDR(下記画像の例では10.0.0.0/16)を指定するインバウンドルールを追加して、ルールを保存します。これでAWS側の準備は完了です。

ROSA側の準備

ROSAクラスターにcluster-adminなどの管理ユーザーでログインして、OpenShiftコンソールのOperatorHubからAWS EFS CSI Driver Operatorをインストールします。「AWS EFS CSI」などのキーワードでOperatorを検索および選択してインストールします。

「ロールARN」では「AWS側の準備」の項目で作成したIAMロールのARNを指定します。また、「更新の承認」が「手動」になっていた場合「自動」を選択して、残りはデフォルトのパラメーターでインストールします。インストールをクリックして数分待つと、Operatorのインストールが完了します。

AWS EFS CSI Driver Operatorを使って、Amazon EFS CSIドライバーをインストールします。OpenShiftコンソールの「管理」メニューの「CustomResourceDefinitions」から「ClusterCSIDriver」をクリックして、「インスタンス」タブの「ClusterCSIDriverの作成」をクリックします。ちなみに、この画面ではAmazon EBS CSI用にebs.csi.aws.com という名前のClusterCSIDriverがデフォルトで作成済みであることを確認できます。これによって、ROSAクラスターは最初からAmazon EBSをストレージクラスとして利用できるようになっています。

下記をコピペして「作成」をクリックしてefs.csi.aws.comという名前のClusterCSIDriverを作成します。

apiVersion: operator.openshift.io/v1
kind: ClusterCSIDriver
metadata:
    name: efs.csi.aws.com
spec:
  managementState: Managed

「作成」をクリックした後に表示される画面で、以下の2つの条件が「True」になるのを待ちます。ここまでの設定間違いがない場合は、すぐに「True」になることを確認できるはずです。

  • AWSEFSDriverNodeServiceControllerAvailable
  • AWSEFSDriverControllerServiceControllerAvailable

Amazon EFSのファイルシステムを利用するためのストレージクラスを、OpenShiftコンソールの「StorageClasses」メニューから作成します。以下はefs.csi.aws.comClusterCSIDriverを利用してefs-csiという名前のストレージクラスを作成するための例です。ここではAmazon EFS CSIドライバーの動的プロビジョニングを利用することを前提としています。

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: efs-csi
provisioner: efs.csi.aws.com
parameters:
  provisioningMode: efs-ap
  fileSystemId: fs-00d1cfae4484ba25d
  directoryPerms: "700"
  gidRangeStart: "1000"
  gidRangeEnd: "2000"
  basePath: "/dynamic_provisioning"

各パラメーターの解説は次のドキュメントをご参照ください。

docs.redhat.com

これによってefs-csiという名前のストレージクラスが作成されます。

これでROSA側の準備も完了です。

Amazon EFSのファイルシステム利用

これまでの手順で作成したefs-csiストレージクラスを利用して、Amazon EFSのファイルシステムをROSAクラスターから利用してみます。OpenShift上で適当なプロジェクト(下記画像の例ではtest-project01)を作成して、その中にPVCを作成します。複数のワーカーノードから同時に読み書きできるようにするために、アクセスモード共有アクセス(RWX)を指定します。PVCの名前とサイズは適宜指定して「作成」をクリックします。

PVCの作成が完了すると、efs-csiストレージクラスのボリュームバイディングモードがImmediateのために、即座にAmazon EFSのファイルシステムのアクセスポイントにバウンドされます。

なお、PVCが作成されると、Amazon EFS CSIドライバーの動的プロビジョニングによってアクセスポイントが自動作成されていきます。efs-csiストレージクラス作成時に指定したグループIDが利用されます。前述したストレージクラスの例だとgidRangeStart: 1000gidRangeEnd: 2000を指定しているので、1000から2000 の未使用のグループIDの中で最も小さい番号が使われていきます。PVCを消すと、該当するAmazon EFSのアクセスポイントも自動的に削除されます。

このテスト用のPVCtest-pvc-01を利用するPodを作成してみます。OpenShiftコンソール右上の「+」アイコンから、下記のYAMLを入力して「作成」をクリックします。

apiVersion: v1
kind: Pod
metadata:
 name: test-efs-01
 namespace: test-project01
spec:
 volumes:
   - name: efs-storage-vol
     persistentVolumeClaim:
       claimName: test-pvc-01
 containers:
   - name: test-efs
     image: centos:latest
     command: [ "/bin/bash", "-c", "--" ]
     args: [ "while true; do touch /mnt/efs-data/verify-efs && echo 'hello efs' && sleep 30; done;" ]
     volumeMounts:
       - mountPath: "/mnt/efs-data"
         name: efs-storage-vol
     securityContext:
       allowPrivilegeEscalation: false
       seccompProfile:
         type: RuntimeDefault

これでtest-efs-01という名前のPodが作成されて、「hello efs」ログや、コンテナ内にマウントされた/mnt/efs-dataディレクトリの読み書きを確認できます。

また、test-pvc-01PVCを利用する他のPodをtest-efs-01Podと同様にtest-efs-02などの名前のPodとして作成すると、他のPodからもtest-pvc-01PVCにあるデータの読み書きが可能なことを確認できます。確認が終了してAmazon EFSのファイルシステムを削除したい場合、PVCを利用しているPod、PVC、ストレージクラス、EFSファイルシステムの順番に削除してください。

Amazon EFSを利用した静的PVの作成

ここまではAmazon EFS CSIドライバーの動的プロビジョニングによるアクセスポイントの自動作成を紹介してきましたが、特定のアクセスポイントを<EFSファイルシステムID>::<アクセスポイントID>のように指定して、静的なPVを作成してPodから利用することもできます。これは、Amazon EFSのバックアップやリストアのために作成されたEFSファイルシステムやそのアクセスポイントを直接指定したいといった場合に有効なシナリオです。この場合は、次のようなYAMLでPVを作成します。EFSファイルシステムのルートディレクトリを指定する場合はvolumeHandle: <ファイルシステムID>というように、ファイルシステムIDだけを指定します。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: efs-static-pv-01
spec:
  capacity: 
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
    - ReadWriteOnce
  claimRef:
    kind: PersistentVolumeClaim
    name: test-static-pvc-01
  persistentVolumeReclaimPolicy: Retain
  storageClassName: efs-static-csi
  csi:
    driver: efs.csi.aws.com
    volumeHandle: fs-00d1cfae4484ba25d::fsap-0a7d8a0cc1d4a11ab
    volumeAttributes:
      encryptInTransit: "true" 

このPVで指定している擬似的なストレージクラスefs-static-csiを指定したPVCを作成できます。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-static-pvc-01
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  storageClassName: efs-static-csi

ここでtest-static-pvc-01PVCが不要になって削除した後に、別のPVCからefs-static-pv-01PVを再利用したい場合、test-static-pvc-01PVCのclaimデータをPVのYAMLから削除する必要があります。下記画像のclaimRef:から下の選択している部分を削除します。なお、動的プロビジョニングの場合と異なり、静的PVを利用している場合はPVCやPVを削除してもアクセスポイントは自動削除されないため、不要になったアクセスポイントは手動削除してください。

ECR Secret Operatorの利用

ROSAやSelf-Managed OpenShift on AWSを使っている場合、OpenShiftクラスターの共通リポジトリとしてAmazon ECRを使っているケースもあると思います。Amazon ECRのプライベートリポジトリからコンテナイメージを取得するにはAmazon IAMベースの認証を必要としますが、認証トークンの有効時間は12時間であり、12時間ごとに認証トークンの再取得が求められます。認証トークンの取得と再取得を自動化するためのOperatorがECR Secret Operatorです。

ECR Secret OperatorはコミュニティーOperatorとカテゴライズされていて、Red Hatからの正式サポートは提供していませんので、注意してください。前述したAWS Elastic File Service CSI Driver OperatorはRed Hat Operatorとカテゴライズされていて、Red Hatからの正式サポートを提供します。

AWS側の準備

ECR Secret Operatorを利用するための前準備として、最初にAmazon ECRのプライベートレジストリにecr-private01リポジトリを作成します。リポジトリ作成手順には、ROSAやOpenShift特有のものはありませんので、Amazon ECRのコンソールか下記のようなawsコマンドなどで作成してください。

$ aws ecr create-repository --repository-name ecr-private01
{
    "repository": {
        "repositoryArn": "arn:aws:ecr:us-east-2:<AWS_ACCOUNT_ID>:repository/ecr-private01",
        "registryId": "<AWS_ACCOUNT_ID>",
        "repositoryName": "ecr-private01",
        "repositoryUri": "<AWS_ACCOUNT_ID>.dkr.ecr.us-east-2.amazonaws.com/ecr-private01",
        "createdAt": "2024-12-13T14:29:47.031000+09:00",
        "imageTagMutability": "MUTABLE",
        "imageScanningConfiguration": {
            "scanOnPush": false
        },
        "encryptionConfiguration": {
            "encryptionType": "AES256"
        }
    }
}

次に、Amazon ECRの認証トークンを取得するためのIAMポリシーを作成します。

$ cat <<EOF > ecr-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken"
            ],
            "Resource": "*"
        }
    ]
}
EOF

$ aws iam create-policy \
  --policy-name rosa-ecr-login-policy \
  --policy-document file://./ecr-policy.json \
  --query 'Policy.Arn' --output text
arn:aws:iam::<AWS_ACCOUNT_ID>:policy/rosa-ecr-login-policy

AWS STSを利用するためのIAMロールを作成して、先ほど作成したIAMポリシーを割り当てます。

$ rosa list oidc-providers
I: Fetching OIDC providers
OIDC PROVIDER ARN                                                                            Cluster ID                        In Use
arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/oidc.op1.openshiftapps.com/289dfj5mirXXXXXX  2el3camm8eh4eq8p19vtcm9n0iujmggq  Yes

$ cat <<EOF > ecr-trust.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/oidc.op1.openshiftapps.com/289dfj5mirXXXXXX"  
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.op1.openshiftapps.com/289dfj5mirXXXXXX:sub": [  
            "system:serviceaccount:ecr-secret-operator:ecr-secret-operator-controller-manager"
          ]
        }
      }
    }
  ]
}
EOF

$ aws iam create-role \
  --role-name rosa-ecr-login-role \
  --assume-role-policy-document file://./ecr-trust.json \
  --query "Role.Arn" --output text
arn:aws:iam::<AWS_ACCOUNT_ID>:role/rosa-ecr-login-role

$ aws iam attach-role-policy \
  --role-name rosa-ecr-login-role \
  --policy-arn arn:aws:iam::<AWS_ACCOUNT_ID>:policy/rosa-ecr-login-policy

先ほど作成したIAMロールでリポジトリのイメージ操作ができるようにするためのポリシーを、最初に作成したプライベートレジストリのecr-private01リポジトリに割り当てます。

$ cat <<EOF > repo-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowPushPull",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::<AWS_ACCOUNT_ID>:role/rosa-ecr-login-role"
                ]
            },
            "Action": [
                "ecr:BatchGetImage",
                "ecr:BatchCheckLayerAvailability",
                "ecr:CompleteLayerUpload",
                "ecr:GetDownloadUrlForLayer",
                "ecr:InitiateLayerUpload",
                "ecr:PutImage",
                "ecr:UploadLayerPart"
            ]
        }
    ]
}
EOF

$ aws ecr set-repository-policy --repository-name ecr-private01 --policy-text file://./repo-policy.json
{
    "registryId": "<AWS_ACCOUNT_ID>",
    "repositoryName": "ecr-private01",
    "policyText": "{\n  \"Version\" : \"2012-10-17\",\n  \"Statement\" : [ {\n    \"Sid\" : \"AllowPushPull\",\n    \"Effect\" : \"Allow\",\n    \"Principal\" : {\n      \"AWS\" : \"arn:aws:iam::<AWS_ACCOUNT_ID>:role/rosa-ecr-login-role\"\n    },\n    \"Action\" : [ \"ecr:BatchGetImage\", \"ecr:BatchCheckLayerAvailability\", \"ecr:CompleteLayerUpload\", \"ecr:GetDownloadUrlForLayer\", \"ecr:InitiateLayerUpload\", \"ecr:PutImage\", \"ecr:UploadLayerPart\" ]\n  } ]\n}"
}

ここでポリシーを割り当てた結果は、Amazon ECRコンソールのリポジトリの「パーミッション」から確認できます。これでAWS側の準備は完了です。

ROSA側の準備

ROSAクラスターのOpenShiftコンソールにcluster-adminなどの管理ユーザーでログインして、OperatorHubからECR Secret Operatorをインストールします。インストールには全てデフォルトのパラメーターを利用します。これによってecr-secret-operatorプロジェクトが存在しない場合に新規作成されます。

ECR Secret OperatorがAWS STSを利用するためのaws-ecr-cloud-credentialsシークレットをecr-secret-operatorプロジェクトに作成します。このシークレットでは、「AWS側の準備」の項目で作成したIAMロールのARNを指定します。OpenShiftコンソールの左サイドメニューの「シークレット」から、「作成」→「キーと値のシークレット」とクリックして、パラメーターは下記の値を指定して作成します。

  • シークレット名: aws-ecr-cloud-credentials
  • キー: credentials
  • 値: 下記の3行を指定
[default]
role_arn = arn:aws:iam::<AWS_ACCOUNT_ID>:role/rosa-ecr-login-role
web_identity_token_file = /var/run/secrets/openshift/serviceaccount/token

これでROSA側の準備も完了です。

Amazon ECRのプライベートリポジトリ認証情報取得

ECR Secret Operatorを利用してプライベートリポジトリの認証情報を取得してみます。適当なプロジェクト(下記画像の例ではtest-project01)をOpenShiftコンソールから作成した後に、インストールしたECR Secret Operatorから「Secret」の下にある「インスタンスの作成」をクリックして、プライベートリポジトリの認証情報を保存するシークレットリソースを作成します。

下記のYAMLを「YAMLビュー」からコピペしてECR Secret Operatorが管理するecr-secret-01シークレットを作成します。このecr-secret-01シークレットによって、10時間ごと(frequency: 10hで指定)に自動取得したプライベートリポジトリの認証情報が、test-project01プロジェクトのecr-auto-generated-secret-01シークレットに自動保存されます。

apiVersion: ecr.mobb.redhat.com/v1alpha1
kind: Secret
metadata:
  name: ecr-secret-01
  namespace: test-project01
spec:
  generated_secret_name: ecr-auto-generated-secret-01
  ecr_registry: <AWS_ACCOUNT_ID>.dkr.ecr.us-east-2.amazonaws.com
  frequency: 10h
  region: us-east-2

すると、以下のようにecr-secret-01によってecr-auto-generated-secret-01シークレットが自動作成されていることが確認できます。ecr-auto-generated-secret-01の中身を見ると、プライベートリポジトリの認証情報(ユーザー名: AWS, パスワード: ランダム文字列)が保存されていることが分かります。

Amazon ECRのプライベートリポジトリのコンテナイメージプッシュとプル

この自動取得した認証情報を利用して、コンテナイメージのビルドとプッシュをしてみます。Rubyのサンプルアプリケーションのソースコードをもとに、コンテナイメージをビルドしてAmazon ECRのプライベートリポジトリにプッシュするためのサンプルYAMLファイルを下記のように修正して、sample-build-config.yamlという名前で保存したYAMLファイルを利用します。

kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: ruby-sample-build 
  namespace: test-project01
spec:
  runPolicy: Serial 
  source: 
    git:
      uri: "https://github.com/openshift/ruby-hello-world"
  strategy: 
    sourceStrategy:
      from:
        kind: "ImageStreamTag"
        name: "ruby:2.5"
      incremental: true
  output: 
    to:
      kind: "DockerImage"
      name: "<AWS_ACCOUNT_ID>.dkr.ecr.us-east-2.amazonaws.com/ecr-private01:latest"
  postCommit: 
      script: "bundle exec rake test"

namespaceは利用しているOpenShiftのプロジェクト名(ここではtest-project01)に変更します。outputの箇所ではECRのプライベートリポジトリのURIに変更します。このYAMLファイルをもとにして、下記のコマンドを実行してコンテナイメージをビルドしてプライベートリポジトリにプッシュします。

$ oc project test-project01
$ oc secrets link builder ecr-auto-generated-secret-01 --for=pull
$ oc create imagestream ruby
$ oc tag openshift/ruby:2.5-ubi8 ruby:2.5
$ oc apply -f sample-build-config.yaml
$ oc start-build ruby-sample-build --wait

これらのコマンドの解説は下記です。OpenShiftコンソールのWeb Terminalで実行できます。

  • oc secrets linkコマンドで、自動作成されたecr-auto-generated-secret-01シークレットをbuilderサービスアカウントに紐付けます。builderサービスアカウントはOpenShiftのプロジェクト作成時に自動作成されるデフォルトのサービスアカウントの1つであり、コンテナイメージのビルド/ビルド中のイメージプル/レジストリへのイメージプッシュ、に利用されます。--for=pullオプションで、コンテナイメージプルとプッシュの時に利用するシークレットリソースに紐付けることを指定します。デフォルトのサービスアカウントの詳細については、下記をご参照ください。 docs.redhat.com
  • rubyイメージストリームtest-project01プロジェクトに作成して、openshiftプロジェクトにあるイメージストリームを利用できるようにoc tagコマンドでタグ付けします。これによって、Ruby 2.5をベースとしたUBI8のコンテナイメージを、イメージビルド専用のコンテナイメージとして利用できるようになります。
  • コンテナイメージビルド用の設定であるruby-sample-buildBuildConfigをsample-build-config.yamlファイルから作成して、oc start-buildコマンドでコンテナイメージのビルドとプッシュを実行します。

前述したoc secrets linkコマンド以外にも、OpenShiftコンソールからYAMLファイルを直接編集してbuilderサービスアカウントへのシークレット紐付けが可能です。

コンテナイメージのビルドとプッシュが正常に完了すると、Amazon ECRのコンソールからリポジトリにイメージがプッシュされたことを確認できます。

リポジトリにプッシュされたイメージからコンテナアプリをデプロイしてみます。test-project01プロジェクトを選択したままにして、OpenShiftコンソールの左サイドメニューの「開発者」→「+追加」から「コンテナーイメージ」をクリックします。

「外部レジストリーからのイメージ名」で、前述の手順でコンテナイメージがプッシュされたAmazon ECRのプライベートリポジトリのイメージURIを指定します。コンテナイメージプルのための認証情報は、前述した手順で作成したecr-auto-generated-secret-01シークレットが自動的に利用されます。残りのパラメーターはデフォルトのままにしておいて「作成」をクリックすることで「コンテナイメージのプル」→「コンテナアプリのデプロイ」→「コンテナアプリ公開のためのURL作成」を自動実行します。

「Routes」に記載してあるURLをクリックして、下記のようなメッセージが表示されればアプリケーションのデプロイは成功です。サンプルアプリケーションのソースコードで指定してあるデータベースをデプロイしていないためにデータベースが実行されていないというエラーメッセージが出力されますが、Amazon ECRの利用テストを目的としているため、ここでは気にしないことにします。

Welcome to an OpenShift Demo App!
(It looks like the database isn't running. This isn't going to be much fun.)

ちなみに、ECR Secret Operatorで作成しているecr-secret-01などのSecretインスタンスから各プロジェクトに自動作成されたecr-auto-generated-secret-01などのSecretリソースは、Secretインスタンスを削除しても自動削除されないので手動削除する必要があります。SecretインスタンスやSecretリソースを削除してAmazon ECRのプライベートリポジトリが不要になった場合は、AWSコンソールやawsコマンドでプライベートリポジトリも適宜削除してください。

参考情報

docs.redhat.com

cloud.redhat.com

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。