GCP Cloud Build子构建失败时,如何回滚服务并取消未完成构建?
解决方案:GCP Cloud Build多子构建失败后的取消与回滚
针对你遇到的多子构建失败时的清理需求,以下是几个可行的最佳实践,替代不稳定的信号陷阱方案:
1. 改用Cloud Build原生编排替代异步脚本提交
放弃用deploy-services.sh异步提交子构建,转而在主构建(cloudbuild-main.yaml)中直接编排所有子构建的生命周期,让主构建统一监控状态并触发失败后的清理:
- 主构建先读取
service-diff.txt,遍历每个服务,用gcloud builds submit提交子构建并同步记录每个子构建的ID到临时文件(比如running-builds.txt)。 - 示例主构建步骤片段:
steps: - name: 'gcr.io/cloud-builders/gcloud' entrypoint: 'bash' args: - '-c' - | > running-builds.txt > completed-deploys.txt while read service; do BUILD_ID=$(gcloud builds submit ./$service --config=./$service/cloudbuild.yaml --async --format="value(id)") echo "$BUILD_ID $service" >> running-builds.txt done < service-diff.txt # 等待所有子构建完成,失败则触发清理 - name: 'gcr.io/cloud-builders/gcloud' entrypoint: 'bash' args: - '-c' - | while read build_id service; do gcloud builds wait $build_id if [ $? -ne 0 ]; then echo "Build $build_id for $service failed, triggering cleanup..." exit 1 fi # 记录已成功部署的版本 VERSION=$(gcloud app versions list --service=$service --limit=1 --format="value(id)") echo "$VERSION $service" >> completed-deploys.txt done < running-builds.txt # 所有成功后执行流量分配步骤 - name: 'gcr.io/cloud-builders/gcloud' args: ['app', 'services', 'set-traffic', ...] # 失败时自动执行清理流程 onFailure: steps: - name: 'gcr.io/cloud-builders/gcloud' entrypoint: 'bash' args: - '-c' - | # 取消未完成的子构建 while read build_id service; do gcloud builds cancel $build_id --quiet || true done < running-builds.txt # 删除已部署的服务版本 while read version service; do gcloud app versions delete $version --service=$service --quiet || true done < completed-deploys.txt
2. 子构建中主动记录部署信息
修改每个服务的cloudbuild.yaml,在部署成功后将版本信息写入主构建的工作空间,确保主构建能准确获取需要回滚的资源:
- 子构建部署步骤示例:
steps: - name: 'gcr.io/cloud-builders/gcloud' args: ['app', 'deploy', 'app.yaml', '--no-promote'] - name: 'gcr.io/cloud-builders/gcloud' entrypoint: 'bash' args: - '-c' - | VERSION=$(gcloud app versions list --service=${_SERVICE_NAME} --limit=1 --format="value(id)") echo "$VERSION ${_SERVICE_NAME}" >> /workspace/completed-deploys.txt substitutions: _SERVICE_NAME: 'service1' # 主构建提交时传入对应服务名
3. 关键注意事项
- 权限配置:确保Cloud Build服务账号拥有
cloudbuild.builds.cancel(取消子构建)和appengine.versions.delete(删除App Engine版本)权限,可通过IAM角色添加。 - 自动化保障:清理命令添加
--quiet参数,避免交互确认,确保流程完全自动化。 - 风险控制:因为部署时用了
--no-promote,未分配流量的版本删除不会影响线上服务,回滚风险极低。
内容的提问来源于stack exchange,提问作者Will Sutton
相关产品推荐
相关产品推荐

