Cloud Build:构建身份与镜像交付

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。

构建代码并推送镜像;Console:Cloud Build → History。

推荐做法#

  • 显式指定 Build SA,按 source 读取、Artifact Registry 写入、日志写入分别授权。
  • .gcloudignore 管源码上传,.dockerignore 管镜像构建上下文;提交前检查文件清单。
  • 构建一次后按 digest 发布;提交者的 actAs 与应用 runtime SA 分开。

常用操作#

替换为实际资源;本段不依赖 lab.env。

PROJECT_ID='REPLACE_PROJECT_ID'
REGION='REPLACE_REGION'

gcloud builds list --project="$PROJECT_ID" --region="$REGION" --limit=10
# 在实际提交的源码目录检查上传清单。
gcloud meta list-files-for-upload

容易踩的坑#

  • Build SUCCESS 不代表服务已部署;新 tag 也不代表代码内容已变化。

Build SA、部署身份、runtime SA 与 Cloud Build service agent 不是同一个身份。 构建能 push,不证明服务能 pull;不要把应用数据权限授给构建身份。

配置说明与完整示例(按需展开)

前置:Artifact Registry;当前目录包含 hello-app/Dockerfile。显式选择构建 SA,避免依赖项目默认构建身份。

构建链路与身份#

builds submit 上传本地源码 → Build SA 执行 Docker build → 推送 Artifact Registry → 写日志。提交者需创建 Build、上传 source 及 Build SA 的 actAs;Build SA 只读 source、写镜像和日志。构建成功不会自动部署 Cloud Run。

准备构建身份#

source lab.env
gcloud services enable cloudbuild.googleapis.com logging.googleapis.com
export BUILD_SA="lab-build@${PROJECT_ID}.iam.gserviceaccount.com"
export HUMAN_EMAIL=$(gcloud config get-value account)
gcloud iam service-accounts create lab-build
gcloud artifacts repositories add-iam-policy-binding lab-images --location="$REGION" --member="serviceAccount:$BUILD_SA" --role=roles/artifactregistry.writer
gcloud projects add-iam-policy-binding "$PROJECT_ID" --member="serviceAccount:$BUILD_SA" --role=roles/logging.logWriter
gcloud iam service-accounts add-iam-policy-binding "$BUILD_SA" --member="user:$HUMAN_EMAIL" --role=roles/iam.serviceAccountUser
export SOURCE_BUCKET="${PROJECT_ID}-build-source"
gcloud storage buckets create "gs://$SOURCE_BUCKET" --location="$REGION" --uniform-bucket-level-access
gcloud storage buckets add-iam-policy-binding "gs://$SOURCE_BUCKET" --member="serviceAccount:$BUILD_SA" --role=roles/storage.objectViewer

构建提交者还需要 Cloud Build 创建构建和上传 source bucket 的权限。Google 管理的 Cloud Build service agent 应保留系统所需角色;不要把 service agent 角色分配给普通用户。

构建可区分的 v2#

本篇 v2 会改变页面内容,供后续 Cloud Run 发布/回滚验收。仅重新构建并改 tag 不会自动得到不同的应用响应。在 Artifact Registry 实验创建的 Dockerfile 上做一次明确修改:

python3 - <<'PYVERSION'
from pathlib import Path
p = Path('hello-app/Dockerfile')
s = p.read_text()
old = r'hello GCP\n'
assert old in s, 'Inspect Dockerfile: expected v1 content is missing'
p.write_text(s.replace(old, r'hello GCP v2\n', 1))
PYVERSION

预期旧镜像仍返回 hello GCP,本次构建的 v2 返回 hello GCP v2。如果此前已修改过 Dockerfile,核对内容后再决定如何生成本次候选版本,不盲目重复替换。

保存 hello-app/cloudbuild.yaml:

steps:
- name: gcr.io/cloud-builders/docker
  args: ['build', '-t', '${_IMAGE}', '.']
images: ['${_IMAGE}']
options:
  logging: CLOUD_LOGGING_ONLY

提交目录是 hello-app;.gcloudignore 控制上传,.dockerignore 控制 Docker build context。提交前在该目录运行 gcloud meta list-files-for-upload,确认只有预期源码,没有 credentials、Secret 或 state 文件。上传规则

gcloud builds submit hello-app \
  --region="$REGION" \
  --config=hello-app/cloudbuild.yaml \
  --service-account="projects/$PROJECT_ID/serviceAccounts/$BUILD_SA" \
  --gcs-source-staging-dir="gs://$SOURCE_BUCKET/source" \
  --substitutions="_IMAGE=${REGION}-docker.pkg.dev/${PROJECT_ID}/lab-images/hello:v2"
gcloud builds list --region="$REGION" --limit=5

--service-account 选择构建执行身份,--gcs-source-staging-dir 指定源码暂存位置,--substitutions 将 _IMAGE 传入 YAML。它们不选择应用的 runtime SA。

验收与清理#

验收:构建状态 SUCCESS、镜像出现 v2、日志可查。失败先区分源码读取、镜像 push、日志写入三种权限。自定义构建 SA

清理源码桶和 SA;镜像仍在 Artifact Registry,需独立清理:

gcloud storage rm --recursive "gs://$SOURCE_BUCKET"
gcloud projects remove-iam-policy-binding "$PROJECT_ID" --member="serviceAccount:$BUILD_SA" --role=roles/logging.logWriter
gcloud artifacts repositories remove-iam-policy-binding lab-images --location="$REGION" --member="serviceAccount:$BUILD_SA" --role=roles/artifactregistry.writer
gcloud iam service-accounts delete "$BUILD_SA"

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭