将配置迁移到 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 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 中充当的身份。
    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 是表示支持性服务名称的字符串。这可以是数据库的名称、随机值或全局服务的标记值。
        • namebinding_name(如果存在);否则为 instance_name。此值通常并不重要。
        • labelVCAP_SERVICES 映射中的键的值,此绑定嵌套在该映射下。
        • plan 是服务计划的名称。例如:“user-provided”“high-availability”。
      2. 通常用于发现/绑定服务的值:

        • tags:可帮助库查找兼容服务的标记列表。这通常包括服务的通用名称,例如 mysql(MySQL 和 MariaDB)、redis(Redis 或 Cloud Memorystore)或 postgres(Postgres 兼容数据库)。
        • credentials:包含客户端库用于执行连接的凭据的对象。大多数客户端库都依赖于包含服务的标准 URI 或 JDBC 格式的 uri 字段。
    6. 将内容保存为 vcap.json

将凭据附加到 Cloud Run 资源

如需附加凭据,请执行以下操作:

  1. 创建一个 Secret 来存储您的 VCAP_SERVICES 环境变量内容,并记下以下命令输出的版本:

    gcloud secrets create APP_NAME-vcap \
      --replication-policy="automatic" \
      --data-file=vcap.json
    
  2. 向应用的服务账号授予读取 Secret 的权限:

    gcloud secrets add-iam-policy-binding APP_NAME-vcap \
      --member="serviceaccount:app-service-account" \
      --role="roles/secretmanager.secretAccessor"
    
  3. 将以下环境变量添加到应用 service.yaml 中的 spec.template.spec.containers[0].env array

    - 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. 在 Web 浏览器中打开该服务网址,访问部署的服务。

恭喜!您已将 Cloud Foundry 应用迁移到 Cloud Run