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"