You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Google Cloud Deploy多目标向Cloud Run部署不同镜像?

解决Google Cloud Deploy多目标部署多个Cloud Run服务的报错问题

问题背景

通过Github Actions将多个镜像推送到Google Cloud Deploy单个版本时,使用Skaffold加载多个rawYaml文件会触发Cloud Build报错:

error: the manifest contains a KRM definition with kind: Service. As a result the manifest is assumed to define a Cloud Run Service. However, 2 KRM definitions were found, a manifest may only define one Cloud Run Service

需求是在单个多目标的每个子目标中部署不同的Cloud Run服务镜像。

错误原因

Cloud Deploy的Cloud Run部署器要求每个部署的manifest只能包含一个Service资源,但当前Skaffold会将所有services/下的yaml文件合并成一个manifest,导致单个manifest中存在多个Service,触发校验报错。

解决方案

方案一:拆分manifest并为子目标指定对应路径

1. 调整Skaffold配置

修改skaffold.yaml,明确声明每个服务的镜像和对应的rawYaml文件:

apiVersion: skaffold/v4beta6
kind: Config

artifacts:
  - image: service-name-1
    context: ./service1 # 替换为该镜像的实际构建上下文路径
  - image: service-name-2
    context: ./service2 # 替换为该镜像的实际构建上下文路径

manifests:
  rawYaml:
    - services/service-name-1.yaml
    - services/service-name-2.yaml

deploy:
  cloudrun: {}

2. 更新Cloud Deploy Target配置

在clouddeploy.yaml中,为每个子Target添加deployParameters指定对应服务的manifest路径:

apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
  name: service-name-1
description: production service 1
run:
  location: projects/coolbeaver/locations/asia-southeast1
deployParameters:
  manifestPaths: ["services/service-name-1.yaml"]
---
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
  name: service-name-2
description: production service 2
run:
  location: projects/coolbeaver/locations/asia-southeast1
deployParameters:
  manifestPaths: ["services/service-name-2.yaml"]

3. 调整Github Actions流程

在Actions步骤中,用Skaffold渲染manifest并创建Cloud Deploy版本:

# 渲染manifest并替换镜像地址
skaffold render --default-repo gcr.io/your-project-id --output ./

# 创建Cloud Deploy版本,指定包含所有服务配置的目录
gcloud deploy releases create release-$(date +%Y%m%d%H%M%S) \
  --delivery-pipeline main-pipeline \
  --region asia-southeast1 \
  --source . \
  --manifests ./

方案二:使用Kustomize生成定制化manifest

如果需要更灵活的配置管理,可以用Kustomize为每个服务生成独立的manifest:

1. 搭建Kustomize目录结构

kustomize/
├── base/
│   ├── service-template.yaml
│   └── kustomization.yaml
└── overlays/
    ├── service1/
    │   └── kustomization.yaml
    └── service2/
        └── kustomization.yaml

2. 编写基础模板和定制化配置

  • base/service-template.yaml(通用Service模板):
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: placeholder
spec:
  template:
    spec:
      containers:
        - image: placeholder-image
  • base/kustomization.yaml:
resources:
  - service-template.yaml
  • overlays/service1/kustomization.yaml(定制service-name-1):
bases:
  - ../../base
images:
  - name: placeholder-image
    newName: service-name-1
patches:
  - patch: |-
      - op: replace
        path: /metadata/name
        value: service-name-1
  • overlays/service2/kustomization.yaml(定制service-name-2):
bases:
  - ../../base
images:
  - name: placeholder-image
    newName: service-name-2
patches:
  - patch: |-
      - op: replace
        path: /metadata/name
        value: service-name-2

3. 更新Skaffold配置

apiVersion: skaffold/v4beta6
kind: Config

artifacts:
  - image: service-name-1
    context: ./service1
  - image: service-name-2
    context: ./service2

manifests:
  kustomize:
    paths:
      - kustomize/overlays/service1
      - kustomize/overlays/service2

deploy:
  cloudrun: {}

4. 调整Github Actions流程

# 渲染所有Kustomize overlay生成manifest
skaffold render --default-repo gcr.io/your-project-id --output manifests/

# 创建Cloud Deploy版本
gcloud deploy releases create release-$(date +%Y%m%d%H%M%S) \
  --delivery-pipeline main-pipeline \
  --region asia-southeast1 \
  --source . \
  --manifests manifests/

核心原理

通过让每个Cloud Run子目标加载单独的、仅包含一个Service的manifest,规避Cloud Deploy的校验限制,同时利用单个Cloud Deploy版本包含所有服务配置,实现多目标的批量部署。

内容的提问来源于stack exchange,提问作者spicyzboss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 14:30:03