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 仕様を実装していますが、Cloud Run ワークロードを GKE などの Kubernetes クラスタに移行する際に Knative に移行する必要はありません

クイックスタート

このクイックスタートでは、シンプルな移行について説明します。

シンプルなリソースの比較

my-app という名前のシンプルな Cloud Run サービスと、それと同等の Kubernetes Deployment を比較します。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. Kubernetes Deployment と一致するように YAML を変更します。

    • kind 属性では、値 ServiceDeployment に置き換えます。
    • apiVersion 属性では、値 serving.knative.dev/v1apps/v1 に置き換えます。
    • metadata.namespace は、デプロイ先の GKE クラスタの Namespace に置き換えます(例: default)。
    • metadataspec.template.metadata に新しいラベルを追加します。
    • spec.template.spec.replicas を使用して一定数のインスタンス(レプリカ)を設定し、spec.template.spec.selector にラベルセレクタを設定します。
  3. kubectl コマンドライン ツールをインストールして使用し、GKE クラスタに my-app.yaml ファイルをデプロイします。

    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 サービスの呼び出しは IAM 起動元の権限の対象ではありません。

  • GKE ではコンテナ間で強力な分離が行われないため、不明なコードや信頼できないコードを実行する必要がある場合は GKE Sandbox の使用を検討してください。

ネットワーキング

Cloud Run では、VPC 内の別のリソースにアクセスするために、サーバーレス VPC アクセス コネクタが必要になります。GKE ワークロードは VPC 内にあるため、コネクタは必要ありません。

Google Kubernetes Engine でサポートされていない機能

次の Cloud Run 機能は GKE では使用できません。

Cloud Run リソースを移行する

以降のセクションでは、Cloud Run サービス、ジョブ、シークレットなど、Cloud Run で使用されるリソースの移行について説明します。

Cloud Run サービスを移行する

Cloud Run サービスは、GKE の次のリソースに移行できます。

  1. Kubernetes Deployment。インスタンスを作成します(Kubernetes では Pod)。
  2. Kubernetes Services。特定のエンドポイントに Deployment を公開します。
  3. Kubernetes HorizontalPodAutoscaler: Deployment を自動的にスケーリングします。

Kubernetes Deployment の属性は、Cloud Run サービスの属性のスーパーセットです。クイックスタートに示すように、apiVersion 属性と kind 属性を apps/v1Deployment に変更した後、次のように変更する必要があります。

  • namespace は、デプロイ先の GKE クラスタの Namespace に置き換えます(例: default)。
  • serviceAccountName は Kubernetes サービス アカウントを参照する必要があります。これは、Workload Identity で IAM サービス アカウントとして機能することもできます。
  • Deployment と Pod の選択に使用される LABELmetadata.labelsspec.template.metadata.labels に追加します。例: app: NAME
  • spec.template で次の操作を行います。
    • replicas 属性を追加して、インスタンスの数を指定します。
    • ラベル LABEL で選択する selector.matchLabels 属性を追加します。
  • Cloud Run サービスが Secret をマウントする場合は、Secret を移行するをご覧ください。
  • 移行された Cloud Run サービスが Virtual Private Cloud のリソースにアクセスしていた場合は、サーバーレス VPC アクセス コネクタを使用する必要はありません。

Kubernetes Deployment を作成したら、それを公開する Kubernetes Service を作成します。

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

次のように置き換えます。

  • NAME: 実際の Service の名前。
  • LABEL: Deployment で定義されているラベル。例: app: NAME
  • PORT: Cloud Run サービスでリクエストを受信するコンテナの containerPort(デフォルトは 8080)。

その後、必要に応じて Kubernetes HorizontalPodAutoscaler を作成して、Pod の数を自動的にスケーリングできます。Kubernetes の水平 Pod 自動スケーリングのドキュメントに従って、HorizontalPodAutoscaler を作成します。Cloud Run サービスの minReplicas 属性 maxReplicas 属性の HorizontalPodAutoscaler の値として、最小インスタンス数autoscaling.knative.dev/minScale)と最大インスタンス数autoscaling.knative.dev/maxScale)の値を使用します。

Cloud Run ジョブを移行する

Cloud Run ジョブは、GKE の Kubernetes Job に移行できます。

Cloud Run ジョブとは異なり、Kubernetes Job は作成時に実行されます。Job を再度実行する場合は、新しい Job を作成する必要があります。

次のサンプルは、Cloud Run ジョブと Kubernetes Job の構造上の違いを示しています。

Cloud Run ジョブKubernetes Job
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 に移行することもできます。

Secret Manager でシークレットを保持する場合は、GKE でシークレットの使用方法を更新する必要があります。

Secret Manager から Kubernetes Secret に移行する場合は、Secret Manager のシークレットと Kubernetes Secret の違いに注意してください。

  • 名前に使用できる文字:
    • Kubernetes Secret: [a-z0-9-.]{1,253}
    • Secret Manager シークレット: [a-zA-Z0-9_-]{1,255}
  • バージョニング: Secret Manager のシークレットはバージョニングされますが、Kubernetes Secret はバージョニングされません。
  • ペイロード: Secret Manager のシークレットには単一の []byte が含まれますが、Kubernetes Secret には map<string, string> が含まれます。

移行戦略

同等のリソースを作成した後、グローバル外部アプリケーション ロードバランサの背後に外部エンドポイントを公開することで、Cloud Run と Google Kubernetes Engine(GKE)間のトラフィックを段階的に移行できます。