从 Cloud Run 迁移到 Google Kubernetes Engine

Cloud Run 和 Kubernetes 都使用标准容器映像作为部署工件,它们都使用声明性 API 模型,其中的资源可以在具有相同标准结构的 YAML 文件中表示。

简介

Cloud Run Admin API v1 旨在最大限度地提高 Kubernetes 的可移植性,例如,Cloud Run Admin API 资源与 Kubernetes 资源具有相同的结构惯例和特性名称。请参阅 Cloud Run 服务 YAML 参考文档

Cloud Run Admin API v1 实现了 Knative Serving API 规范,但您无需迁移到 Knative 即可将您的 Cloud Run 工作负载迁移到 Kubernetes 集群(如 GKE)。

快速入门

本快速入门是一个简单的迁移示例。

简单的资源对比

将以下名为 my-app 的简单 Cloud Run 服务与等效的 Kubernetes 部署进行对比。请注意,YAML 文件几乎完全相同。

但是,以 blue 颜色显示的部分有些许差异,迁移时需要予以更改;此外,应添加以 green 颜色显示的部分。

Cloud Run 服务Kubernetes Deployment
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: my-app
  namespace: 'PROJECT_NUMBER'
spec:
  template:
    spec:
      containers:
      - image: gcr.io/cloudrun/hello
        env:
        - name: HELLO
          value: world
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: default
  labels:
    app: my-app
spec:
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - image: gcr.io/cloudrun/hello
        env:
        - name: HELLO
          value: world
  replicas: 3
  selector:
    matchLabels:
      app: my-app

将简单的 Cloud Run 服务迁移到 GKE

  1. 将服务 YAML 文件下载到当前目录:

    gcloud run services describe my-app --format export > my-app.yaml
  2. 修改 YAML 以与 Kubernetes 部署匹配:

    • 对于“kind”属性,请将值“Service”替换为“Deployment
    • 对于“apiVersion”属性,请将值“serving.knative.dev/v1”替换为“apps/v1
    • metadata.namespace 替换为要部署到的 GKE 集群的命名空间,例如 default
    • metadataspec.template.metadata 下添加新标签。
    • 使用 spec.template.spec.replicas 设置固定数量的实例(即“副本数”),并在 spec.template.spec.selector 中设置标签选择器。
  3. 安装并使用 kubectl 命令行工具将 my-app.yaml 文件部署到您的 GKE 集群:

    kubectl apply -f ./my-app.yaml
  4. 将部署作为服务公开:

    kubectl expose deployment my-app --type LoadBalancer --port 80 --target-port 8080

从 Cloud Run 迁移到 GKE 时的注意事项

集群

  • Cloud Run 是一个全代管式平台,而 GKE 则需要更多平台管理。如果您尚未创建 GKE 集群,请使用 GKE Autopilot

  • GKE 工作负载的可扩缩性受集群大小的限制。如果您未使用 Autopilot 集群,请考虑使用节点自动预配集群自动扩缩器来调整集群的大小。

  • Cloud Run 具有内置可用区冗余特性,因此您可以迁移到区域级集群并预配足够的副本,以确保您的服务在所选 Google Cloud 区域发生可用区级服务中断时能够灵活应对。

价格

Cloud Run 将对所用资源收费,而 GKE 则会对预配资源收费

安全性

  • 与 Cloud Run 相反,调用 GKE 服务不受 IAM 调用方权限的约束。

  • 由于 GKE 不会在容器之间提供强有力的隔离,因此如果您需要执行未知代码或不可信代码,请考虑使用 GKE Sandbox

网络

Cloud Run 需要使用无服务器 VPC 访问通道连接器来访问 VPC 中的其他资源。而 GKE 工作负载直接位于 VPC 中,因此无需连接器。

Google Kubernetes Engine 不支持的功能

以下 Cloud Run 功能不适用于 GKE:

迁移 Cloud Run 资源

以下部分介绍如何迁移 Cloud Run 中使用的资源,例如 Cloud Run 服务、作业和 Secret。

迁移 Cloud Run 服务

您可以将 Cloud Run 服务迁移到 GKE 上的以下资源:

  1. Kubernetes 部署,用于创建实例(在 Kubernetes 中称为“Pod”)。
  2. Kubernetes 服务,用于在特定端点公开部署。
  3. Kubernetes Pod 横向自动扩缩器:用于自动扩缩部署。

Kubernetes 部署的特性是 Cloud Run 服务特性的超集。如快速入门中所示,将 apiVersionkind 特性更改为 apps/v1Deployment 后,您还需要更改以下内容:

  • namespace 替换为要部署到的 GKE 集群命名空间,例如 default
  • serviceAccountName 应引用一个 Kubernetes 服务账号,可以选择将该账号用作 Workload Identity Federation for GKE 的 IAM 服务账号。
  • metadata.labelsspec.template.metadata.labels 中添加 LABEL,以用于选择部署和 pod。例如 app: NAME
  • spec.template 下:
    • 添加 replicas 特性以指定“实例”数量。
    • 添加在标签 LABEL 上选择的 selector.matchLabels 属性。
  • 如果您的 Cloud Run 服务装载了 Secret,请参阅迁移 Secret
  • 如果迁移的 Cloud Run 服务已能够访问 Virtual Private Cloud 上的资源,则无需使用无服务器 VPC 访问通道连接器。

创建 Kubernetes 部署后,创建 Kubernetes 服务来公开部署:

apiVersion: v1
kind: Service
metadata:
  name: NAME
spec:
  selector:
    LABEL
  ports:
    - protocol: TCP
      port: 80
      targetPort: PORT

您需要进行如下替换:

  • NAME:您的服务的名称。
  • LABEL:您的部署中定义的标签。例如 app: NAME
  • PORT:在 Cloud Run 服务中接收请求的容器的 containerPort,默认为 8080

然后,您可以视需要创建 Kubernetes Pod 横向自动扩缩器以自动扩缩 Pod 的数量。按照 Kubernetes Pod 横向自动扩缩文档来创建 HorizontalPodAutoscaler。使用 Cloud Run 服务的实例数下限 (autoscaling.knative.dev/minScale) 和实例数上限 (autoscaling.knative.dev/maxScale) 值来作为 HorizontalPodAutoscalerminReplicasmaxReplicas 特性的值。

迁移 Cloud Run 作业

您可以将 Cloud Run 作业迁移到 GKE 上的 Kubernetes 作业

与 Cloud Run 作业相反,Kubernetes 作业在创建时执行。如果要再次执行该作业,则需要创建一个新作业。

以下示例展示了 Cloud Run 作业和 Kubernetes 作业之间的结构差异:

Cloud Run 作业Kubernetes 作业
apiVersion: run.googleapis.com/v1
kind: Job
metadata:
  name: my-job
spec:
  template:
    spec:
      template:
        spec:
          containers:
          - image: us-docker.pkg.dev/cloudrun/container/job
apiVersion: batch/v1
kind: Job
metadata:
  name: my-job
spec:
  template:
    spec:
      containers:
      - image: us-docker.pkg.dev/cloudrun/container/job

迁移 Secret

您可以将现有 Secret 保留在 Secret Manager 中,也可以将其迁移到 Kubernetes Secret 中。

如果您选择将 Secret 保留在 Secret Manager 中,则需要更新在 GKE 上使用 Secret 的方式

如果您选择从 Secret Manager 迁移到 Kubernetes Secret,请注意 Secret Manager 中的 Secret 与 Kubernetes Secret 之间存在以下差异:

  • 名称中允许使用的字符
  • 版本控制:Secret Manager 中的 Secret 可以有版本控制,而 Kubernetes Secret 则没有版本控制。
  • 载荷:Secret Manager 中的 Secret 包含一个 []byte,而 Kubernetes Secret 则包含 map<string, string>

迁移策略

创建等效资源后,您需要公开全球外部应用负载均衡器后面的外部端点,这样您便可以在 Cloud Run 和 Google Kubernetes Engine (GKE) 之间逐步迁移流量。