將 Cloud Foundry 設定遷移至 Cloud Run

您必須為每個要遷移至 Cloud Run 的 Cloud Foundry 應用程式,完成設定遷移程序。設定遷移作業包含下列項目:

  • 將 Cloud Foundry manifest.yaml 轉換為 Cloud Run service.yaml
  • 將任何後端服務附加至應用程式,以便部署至 Cloud Run。
  • 將應用程式部署至 Cloud Run 服務。

manifest.yaml 轉換為 service.yaml

您必須將 Cloud Foundry 資訊清單和/或 cf CLI 旗標,轉換為對應的 Cloud Run 服務定義 YAML。

Cloud Run 要求每個應用程式都有專屬的服務 YAML 檔案。如要將 Cloud Foundry 資訊清單中的應用程式遷移至服務 YAML 檔案,請按照下列步驟操作:

  1. 收集下表列出的應用程式屬性。 如果應用程式層級的屬性未經過修改,可能已遭全域 Cloud Foundry 平台設定覆寫。如要取得實際值,請參閱平台管理員提供的說明文件。

    應用程式屬性 cf CLI 第 6 版旗標 說明
    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-access-egress 平台管理員希望應用程式使用的 VPC 輸出名稱。
    custom-audiences 可向應用程式驗證的自訂目標對象。
    serviceAccountName 應用程式在 Google Cloud 中扮演的身分。
    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

附加任何後端服務

您必須建構 VCAP_SERVICES 環境變數,才能讓 Cloud Foundry 應用程式 (例如 Spring 或 Steeltoe) 注入及探索服務。您必須為要遷移的每個應用程式執行這項操作。詳情請參閱 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:服務方案名稱。例如「使用者提供」、「高可用性」。
      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/dbnameMySQL 說明文件可協助您建立 URI 字串。通訊埠通常是 3306
  • username 連線使用者名稱,即使包含在 uri 中,部分程式庫仍會要求提供
  • password 連線密碼,即使包含在 uri 中,部分程式庫仍會要求提供

Redis

Redis 程式庫通常會預期使用 redis 標記。credentials 中通常會包含下列鍵:

  • uri 範本:redis://:password@host:port/dbunumber

IANA Redis URI 說明文件可協助您建立 URI 字串。通訊埠通常是 6379

RabbitMQ

RabbitMQ 程式庫通常會預期 rabbitmq 標記和 credentials 中的下列鍵:

  • uri 範本:amqp://username:password@host:port/vhost?query

RabbitMQ 說明文件可協助建立 URI 字串。通訊埠通常是 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
    

    稍候片刻,等待部署作業完成。成功完成後,指令列會顯示服務網址。

  3. 在網路瀏覽器中開啟服務網址,以造訪您所部署的服務。

恭喜!您已將 Cloud Foundry 應用程式遷移至 Cloud Run