克隆实例时,如何保持源实例的 IAM 绑定不被复制?
解读
在国内金融、政企及互联网大厂的上云实践中,“克隆”常被用作快速复制一套灰度或压测环境。
但 Cloud SQL 的克隆默认会把源实例的 IAM 绑定(project 级、实例级、细粒度 Cloud SQL 角色)一并带过去,导致新实例继承了生产库的高权限账号,一旦灰度环境被攻破或误操作,将直接放大爆炸半径。
因此,面试官真正想考察的是:
- 你是否理解 Cloud SQL 克隆的**“元数据继承”边界**;
- 你是否能在零停机、零重建的前提下,把 IAM 绑定“剥离”掉;
- 你是否熟悉国内合规场景下**“最小可用权限”+“权限二次审批”**的落地套路。
知识点
- Cloud SQL 克隆原理:
- 基于底层磁盘快照+事务日志重放,不重启源实例;
- 克隆出来的新实例继承源实例的 metadata,包括 authorizedNetworks、labels、实例级 IAM policy(即 cloudsql.instances.setIamPolicy 那一份)。
- IAM 继承粒度:
- project 级 IAM 绑定(如 roles/cloudsql.admin 作用在整个 project)天然对新实例生效,无法通过克隆参数隔离;
- 实例级 IAM 绑定(即 set-iam-policy 直接绑在实例上)会被克隆带走,必须显式清理。
- 国内可落地的三条技术路径:
- 路径 A:克隆后立刻执行
gcloud sql instances remove-iam-policy-binding,用脚本批量撤销; - 路径 B:在组织策略里启用 “iam.disableServiceAccountKeyCreation”+“iam.uniformBucketLevelAccess” 等约束,把高危角色直接禁止;
- 路径 C:采用 Terraform 蓝绿方案,克隆时把
deletion_protection=false、iam_policy=[]写进 .tf,apply 时强制覆盖空绑定,实现 IaC 一次成型。
- 路径 A:克隆后立刻执行
- 合规加分项:
- 把清理动作接入国内云审计(CloudAuditLogs → 自研 SIEM),双人复核;
- 对灰度项目启用 “VPC-SC 服务边界”,即使 IAM 误继承,也无法跨边界访问生产数据。
答案
步骤一:克隆时显式指定新实例 ID 与空标签,避免运维人员误以为是源实例:
gcloud sql instances clone prod-order-db \
staging-order-db-$(date +%m%d) \
--no-async
步骤二:克隆完成后立即清空实例级 IAM 绑定(project 级角色由组织策略兜底,不重复劳动):
# 拉取当前 policy
gcloud sql instances get-iam-policy staging-order-db-0422 \
--format=json > /tmp/policy.json
# 用 jq 去掉所有 members,生成空绑定
jq '.bindings=[]' /tmp/policy.json > /tmp/empty-policy.json
# 回写空 policy
gcloud sql instances set-iam-policy staging-order-db-0422 \
/tmp/empty-policy.json
步骤三:把上述两条命令封装进国内常用的“云效/蓝鲸”流水线,强制卡点 + 审计日志,实现“克隆即清权”。
核心结论:Cloud SQL 克隆无法通过参数跳过 IAM 继承,必须在克隆后“立即置空”实例级 IAM 绑定,并用组织策略+流水线保证无人为遗漏。
拓展思考
- 如果源实例用了云 IAM + 自建 DB 账号混合模式,克隆后还需手动删除 postgres/mysql.user 表中继承来的高权账号,否则会出现“IAM 清空了,但数据库内账号还能登录”的权限逃逸场景。
- 在国内多项目隔离场景下,可预置一条组织策略约束:
强制所有克隆实例禁用公网 IP,把 IAM 误继承带来的风险锁定在 VPC 内。constraint: "constraints/sql.restrictPublicIp" - 未来 Google Cloud 若推出 “clone 时指定 --clear-iam-bindings” 参数,仍需保持脚本兜底,因为组织策略的生效范围可能滞后于项目加入,**“防御式编程”**才是国内金融级合规的常态。