Cloud Run に構成を移行する

Cloud Run に移行する Cloud Foundry アプリケーションごとに構成の移行プロセスを完了する必要があります。構成の移行では以下の処理が行われます。

  • Cloud Foundry manifest.yaml を Cloud Run service.yaml に変換する。
  • Cloud Run にデプロイするためにバッキング サービスとアプリケーションを接続する。
  • Cloud Run サービスにアプリケーションをデプロイする。

manifest.yamlservice.yaml に変換する

Cloud Foundry マニフェストまたは cf CLI フラグを同等の Cloud Run サービス定義 YAML に変換する必要があります。

Cloud Run では、アプリケーションごとに独自のサービス YAML ファイルが必要です。Cloud Foundry マニフェスト内のアプリケーションをサービス YAML ファイルに移行するには:

  1. アプリケーションについて、次の表に示すプロパティを収集します。アプリケーション レベルで変更されないプロパティは、グローバル Cloud Foundry プラットフォームの構成によってオーバーライドされる可能性があります。実際の値については、プラットフォーム管理者が提供するドキュメントをご覧ください。

    アプリケーションのプロパティcf CLI v6 フラグ 説明
    name NAME 引数 Cloud Foundry 内のアプリケーションの一意の名前。
    command -c /bin/sh または /bin/bash で実行されるコマンド。
    disk_quota -k アプリケーションに割り当てられるディスクの量。

    有効な単位: MMBGr B

    デフォルト(推定): 1G

    docker.image --docker-image-o 実行するアプリケーションを含むイメージ。
    health-check-http-endpoint なし ヘルスチェック タイプが HTTP の場合に HTTP の状態を判断するために使用されるエンドポイント。

    デフォルト: /

    health-check-invocation-timeout なし 個々のポートと HTTP ベースのヘルスチェックの間の時間(秒)。

    デフォルト: 1

    health-check-type --health-check-type-u アプリケーションで実行するヘルスチェックのタイプ。有効な値: porthttpnoneprocess

    デフォルト: port

    instances -i Cloud Foundry が実行するアプリのインスタンスの数。

    デフォルト: 1

    memory -m アプリケーションのインスタンスごとのメモリ上限。

    有効な単位: MMBGGB

    デフォルト(推定): 1G

    timeout -t アプリの起動から最初のヘルスチェックで正常と判断されるまでの秒数。

    デフォルト(推定): 60

  2. Google Cloud プロジェクトと Cloud Run の設定について、次の情報を収集します。

    プロパティ 説明
    project_number デプロイ先の Google Cloud プロジェクトのプロジェクト番号。
    region アプリのデプロイ先のリージョン。
    vpc-access-connector プラットフォーム管理者がアプリケーションを配置する VPC コネクタ名。
    vpc-access-egress プラットフォーム管理者がアプリケーションを配置する VPC 下り(外向き)の名前。
    custom-audiences アプリケーションの認証が可能なカスタム オーディエンス。
    serviceAccountName Google Cloud でのアプリケーションの ID。
    image 前の手順で作成したアプリケーションのイメージ。
  3. プロジェクトのルートにある service.yaml ファイルに次のテンプレートを挿入します。

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  # Set this to be the name of your app
  name: "APP_NAME"
  # Set this to be the project number of the project you're deploying to.
  namespace: "PROJECT_NUMBER"
  labels:
    # Set this to be the region you're deploying in.
    cloud.googleapis.com/location: REGION
    migrated-from: cloud-foundry
  annotations:
    run.googleapis.com/ingress: internal-and-cloud-load-balancing
spec:
  template:
    metadata:
      annotations:
        # Set to the greater of 1 or the `instances` attribute.
        autoscaling.knative.dev/minScale: '1'
        # Set to the greater of 1 or the `instances` attribute.
        autoscaling.knative.dev/maxScale: '1'
        run.googleapis.com/cpu-throttling: CPU_ALLOCATION
        run.googleapis.com/startup-cpu-boost: 'true'
        # Set to true if you rely on sticky sessions. These will be turned
        # on in Cloud Foundry if the server sends a JSESSIONID cookie back
        # on responses.
        run.googleapis.com/sessionAffinity: 'false'
        run.googleapis.com/execution-environment: gen2
        # Set the following values to match what your platform administrator recommends.
        run.googleapis.com/vpc-access-connector: ADMINISTRATOR_PROVIDED
        run.googleapis.com/vpc-access-egress: ADMINISTRATOR_PROVIDED
        run.googleapis.com/custom-audiences: ADMINISTRATOR_PROVIDED
    spec:
      # CF doesn't limit, but CR has a max of 1000.
      containerConcurrency: 1000
      # Default value for gorouter in PCF.
      timeoutSeconds: 900
      # Set the following value to match what your platform administrator recommends.
      serviceAccountName: ADMINISTRATOR_PROVIDED
      containers:
      - name: user-container
        # Set the following value to either:
        # - The image you built for your application in the last section of the guide.
        # - The docker.image attribute of your app's configuration if it's a Docker app.
        image: IMAGE
        # Set `command` based on the following rules:
        # - If your app has no `command` attribute: null.
        # - If your app has a docker.image attribute: ['/bin/sh', '-c']
        # - Otherwise: ['/bin/bash', '-c']
        command: null
        # Set `args` based on the following rules:
        # - If your app has no `command` attribute: null.
        # - If your app has a `command` attribute: ['value of command']
        args: null
        ports:
          # Set name based on the following rules:
          # - If your app is HTTP/2 or gRPC: "h2c"
          # - Else: "http1"
        - name: HTTP1_OR_H2C
          containerPort: 8080
        env:
          # For each key/value pair in your space's running environment variable groups,
          # which can be retried by running `cf running-environment-variable-group`,
          # add the following:
        - name: KEY
          value: VALUE
          # For each key/value pair in your manifest's `env` map, add the following:
        - name: KEY
          value: VALUE
          # Populate MEMORY_LIMIT with the amount of memory supplied to this instance
          # in MiB with 'M' as a suffix.
        - name: MEMORY_LIMIT
          value: '0M'
          # Set the following values in the JSON below:
          # - `application_name` and `name` to match metadata.name in this file.
          # - `application_uris` and `uris` to be the URI you want to assign the app on the
          #    load balancer.
          # - `limits.disk` to be the amount (in MiB) of disk assigned to your app.
          #   The amount will be in the `disk_quota` attribute of the CF manifest, or a
          #   default value for your cluster, typically 1GiB.
          # - `limits.mem` to be the amount (in MiB) of memory assigned to your app.
          #   The amount will be in your `memory` attribute of the CF manifest, or a
          #   default value for your cluster, typically 1GiB.
          # - `space_name` to be the value of metadata.space in this file.
        - name: VCAP_APPLICATION
          value: |-
                  {
                    "application_id": "00000000-0000-0000-0000-000000000000",
                    "application_name": "app-name",
                    "application_uris": [],
                    "limits": {
                      "disk": 1024,
                      "mem": 256
                    },
                    "name": "app-name",
                    "process_id": "00000000-0000-0000-0000-000000000000",
                    "process_type": "web",
                    "space_name": "none",
                    "uris": []
                  }
        resources:
          limits:
            # Set memory limit to be the sum of the memory and disk assigned to your app in CF.
            # 
            # Disk amount will be in the `disk_quota` attribute of the CF manifest, or a
            # default value for your cluster, typically 1GiB.
            #
            # Memory will be in your `memory` attribute of the CF manifest, or a
            # default value for your cluster, typically 1GiB.
            memory: MEMORY_LIMIT
            # Set cpu according to the following calculation:
            #
            # 1. Take the amount of memory in your `memory` attribute of the CF
            #    manifest, or a default value for your cluster, typically 1GiB.
            # 2. Divide that by the total amount of memory on the underlying BOSH VM.
            # 3. Multiply that by the total number of CPUs on the BOSH VM.
            # 4. Find the nearest valid value based on the rules in:
            #    https://cloud.google.com/run/docs/configuring/cpu#setting
            cpu: CPU_LIMIT
        # If `health-check-type` is "process" or "none", delete the startupProbe section.
        startupProbe:
          # If `health-check-type` is "port" or blank, delete the httpGet section.
          httpGet:
            # Set to be the value of `health-check-http-endpoint` or / if blank.
            path: CHECK_PATH
            port: 8080
          # If `health-check-type` is "http", delete the tcpSocket section.
          tcpSocket:
            port: 8080
          # Set to the value of `health-check-invocation-timeout` or 1
          timeoutSeconds: 1
          # Set failure threshold to be the following calculation:
          #
          # 1. Take the `timeout` from the CF manifest, use 60 if unset.
          # 2. Divide by 2.
          # 3. Round up to the nearest integer.
          failureThreshold: 1
          successThreshold: 1
          periodSeconds: 2
        # If `health-check-type` is "process" or "none", delete the livenessProbe section.
        livenessProbe:
          # If `health-check-type` is "port" or blank, delete the httpGet section.
          httpGet:
            # Set to be the value of `health-check-http-endpoint` or / if blank.
            path: CHECK_PATH
            port: 8080
          # If `health-check-type` is "http", delete the tcpSocket section.
          tcpSocket:
            port: 8080
          # Set to the value of `health-check-invocation-timeout` or 1.
          timeoutSeconds: 1
          failureThreshold: 1
          successThreshold: 1
          periodSeconds: 30
  traffic:
  - percent: 100
    latestRevision: true

バッキング サービスを接続する

Spring や Steeltoe などの Cloud Foundry アプリケーションによるサービス インジェクションと検出を可能にするため、VCAP_SERVICES 環境変数を作成する必要があります。この操作は、移行するアプリケーションごとに行う必要があります。詳細については、Cloud Foundry VCAP_SERVICES のドキュメントをご覧ください。

アプリケーションがすでに Cloud Foundry で実行されており、Cloud Run で同じサービスに接続する必要がある場合は、既存の環境変数を使用できます。それ以外の場合は、新しい VCAP_SERVICES を作成する必要があります。

VCAP_SERVICES 環境変数を構成するには:

  1. 既存の VCAP_SERVICES の場合:

    1. cf env APP_NAME を実行して、VCAP_SERVICES 環境変数を取得します。
    2. うまくいかない場合:
      1. Cloud Foundry でアプリケーションに接続します(cf ssh APP_NAME を実行)。
      2. env コマンドを実行して、VCAP_SERVICES の出力を取得します。
      3. exit を実行して SSH セッションを終了します。
    3. VCAP_SERVICES 値を vcap.json という名前の新しいファイルに保存します。
  2. サービスを追加する場合、または Cloud Foundry とは異なるサービスに接続する場合は、新しい VCAP_SERVICES を作成します。

    1. テキスト エディタで、空の JSON マップ({})を作成します。
    2. 追加するサービスごとに、次の操作を行います。
    3. アプリがバインディングを検出する方法については、追加するタイプの VCAP_SERVICES を解析するためにアプリが使用するライブラリのドキュメントを参照してください。
    4. サービス プロバイダの名前がまだ存在しない場合は、mysqlpostgresqlelasticsearch などの名前を使用してキーをマップに追加します。値を空の配列に設定します。
    5. 次のプロパティを持つオブジェクトを配列に追加します。

      1. 通常、サービスの検出やバインドに使用されないメタデータ:

        • binding_name。サービスでアプリケーションの権限を付与するリソースを表す文字列。これは、データベースのユーザー名、ファイアウォール ルール、サービス アカウント名などです。
        • instance_name。バッキング サービスの名前を表す文字列。データベースの名前、ランダムな値、グローバル サービスの標識値などを指定できます。
        • name。存在する場合は binding_name、存在しない場合は instance_name。通常、この値は重要ではありません。
        • label。このバインディングがネストされている VCAP_SERVICES マップ内のキーの値。
        • plan。サービスプランの名前。例: user-provided、high-availability など。
      2. サービスの検出やバインドによく使用される値:

        • tags。ライブラリが互換性のあるサービスを見つける際に役立つタグのリスト。多くの場合、サービスの共通名(MySQL と MariaDB では mysql、Redis や Cloud Memorystore の場合は redis、Postgres と互換性のあるデータベースの場合は postgres など)が含まれます。
        • credentials。クライアント ライブラリが接続を実行するために使用する認証情報を含むオブジェクト。ほとんどのクライアント ライブラリは、サービスの標準 URI または JDBC 形式を含む uri フィールドに依存しています。
    6. 内容を vcap.json として保存します。

Cloud Run リソースに認証情報を適用する

認証情報を適用するには:

  1. シークレットを作成して VCAP_SERVICES 環境変数の内容を保持し、次のコマンドで出力されたバージョンをメモします。

    gcloud secrets create APP_NAME-vcap \
      --replication-policy="automatic" \
      --data-file=vcap.json
    
  2. アプリケーションのサービス アカウントにシークレットの読み取り権限を付与します。

    gcloud secrets add-iam-policy-binding APP_NAME-vcap \
      --member="serviceaccount:app-service-account" \
      --role="roles/secretmanager.secretAccessor"
    
  3. 次の環境変数を spec.template.spec.containers[0].env array 内のアプリケーション service.yaml に追加します。

    - name: VCAP_SERVICES
      valueFrom: 
        secretKeyRef:
          key: Version output by step 1
          name: APP_NAME-vcap
    

一般的なバッキング サービスのテンプレート

以降のセクションでは、よく使用されるバッキング サービスについて説明します。

MySQL

通常、MySQL ライブラリでは mysql タグが使用されます。credentials に次のキーを含めるのが一般的です。

  • uri テンプレート: mysql://username:password@host:port/dbname。URI 文字列の作成については、MySQL のドキュメントをご覧ください。通常、ポートは 3306 です。
  • username: 接続のユーザー名。uri に含まれている場合でも、一部のライブラリでは必須です。
  • password: 接続のパスワード。uri に含まれている場合でも、一部のライブラリでは必須です。

Redis

通常、Redis ライブラリでは redis タグが使用されます。credentials に次のキーを含めるのが一般的です。

  • uri テンプレート: redis://:password@host:port/dbunumber

URI 文字列の作成については、IANA Redis URI のドキュメントをご覧ください。通常、ポートは 6379 です。

RabbitMQ

通常、RabbitMQ ライブラリでは rabbitmq タグと credentials の次のキーが使用されます。

  • uri テンプレート: amqp://username:password@host:port/vhost?query

URI 文字列の作成については、RabbitMQ のドキュメントをご覧ください。通常、ポートは 5672 です。

ユーザー提供のサービス

ユーザー提供のサービスは Cloud Foundry の特別なタイプのサービスで、任意の認証情報を挿入できます。ラベルは常に user-provided です。タグは -t フラグを使用して cf create-user-provided-service に渡される値で、認証情報は -p フラグの内容です。

アプリケーションのデプロイ

完全に移行された Cloud Foundry アプリケーションを Cloud Run サービスにデプロイするには:

  1. Cloud Run 環境を設定します(まだ設定していない場合)。

  2. 次のコマンドを実行します。

    gcloud run services replace service.yaml
    

    デプロイが完了するまで少しお待ちください。成功すると、コマンドラインにサービス URL が表示されます。

  3. このサービス URL をウェブブラウザで開き、デプロイしたコンテナにアクセスします。

これで完了です。Cloud Foundry アプリケーションが Cloud Run に移行されました。