從 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. 將 Deployment 公告為服務:

    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 服務時,不需具備身分與存取權管理叫用者權限

  • 由於 GKE 不會在容器之間提供嚴密的隔離機制,因此如果需要執行未知或不受信任的程式碼,建議使用 GKE Sandbox

網路

Cloud Run 需要無伺服器虛擬私有雲存取連接器,才能存取虛擬私有雲中的其他資源。GKE 工作負載直接位於 VPC 中,不需要連接器。

Google Kubernetes Engine 不支援的功能

下列 Cloud Run 功能不適用於 GKE:

遷移 Cloud Run 資源

以下各節說明如何遷移 Cloud Run 中使用的資源,例如 Cloud Run 服務、工作和密鑰。

遷移 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 服務帳戶,該帳戶可選擇性地做為 IAM 服務帳戶,搭配 GKE 適用的 Workload Identity 聯盟使用。
  • metadata.labelsspec.template.metadata.labels 中新增 LABEL,用於選取部署作業和 Pod。例如:app: NAME
  • 在「spec.template」下方:
    • 新增 replicas 屬性,指定「執行個體」數量。
    • 新增 selector.matchLabels 屬性,在標籤 LABEL 上選取。
  • 如果 Cloud Run 服務會掛接密鑰,請參閱遷移密鑰
  • 如果遷移的 Cloud Run 服務存取虛擬私有雲上的資源,則不需要使用無伺服器虛擬私有雲存取連接器。

建立 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) 值,做為 minReplicasmaxReplicas 屬性的值 HorizontalPodAutoscaler

遷移 Cloud Run worker 集區

您可以將 Cloud Run worker 集區遷移至 GKE 上的 Kubernetes 部署作業

下列範例顯示 Cloud Run 工作站集區和 Kubernetes 部署作業的結構差異。

Cloud Run worker 集區Kubernetes Deployment
apiVersion: run.googleapis.com/v1
kind: WorkerPool
metadata:
  name: my-app
  annotations:
    run.googleapis.com/manualInstanceCount: '1'
spec:
template:
    metadata:
      labels:
      app: my-app
    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 工作

您可以將 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 Manager 中,也可以將密鑰遷移至 Kubernetes 密鑰。

如果您選擇將密鑰保留在 Secret Manager 中,則需要更新在 GKE 上使用密鑰的方式

如果您選擇從 Secret Manager 遷移至 Kubernetes 密鑰,請注意 Secret Manager 密鑰與 Kubernetes 密鑰之間的差異:

  • 名稱可用的字元
  • 版本控管:Secret Manager 中的密鑰會進行版本控管,但 Kubernetes 密鑰不會。
  • 酬載:Secret Manager 中的密鑰包含單一 []byte,而 Kubernetes 密鑰則包含 map<string, string>

遷移策略

建立對等資源後,公開全球外部應用程式負載平衡器後方的外部端點,即可在 Cloud Run 和 Google Kubernetes Engine (GKE) 之間逐步遷移流量。