克隆实例时,如何保持源实例的 IAM 绑定不被复制?

解读

在国内金融、政企及互联网大厂的上云实践中,“克隆”常被用作快速复制一套灰度或压测环境
但 Cloud SQL 的克隆默认会把源实例的 IAM 绑定(project 级、实例级、细粒度 Cloud SQL 角色)一并带过去,导致新实例继承了生产库的高权限账号,一旦灰度环境被攻破或误操作,将直接放大爆炸半径
因此,面试官真正想考察的是:

  1. 你是否理解 Cloud SQL 克隆的**“元数据继承”边界**;
  2. 你是否能在零停机、零重建的前提下,把 IAM 绑定“剥离”掉;
  3. 你是否熟悉国内合规场景下**“最小可用权限”+“权限二次审批”**的落地套路。

知识点

  1. Cloud SQL 克隆原理:
    • 基于底层磁盘快照+事务日志重放不重启源实例
    • 克隆出来的新实例继承源实例的 metadata,包括 authorizedNetworks、labels、实例级 IAM policy(即 cloudsql.instances.setIamPolicy 那一份)。
  2. IAM 继承粒度:
    • project 级 IAM 绑定(如 roles/cloudsql.admin 作用在整个 project)天然对新实例生效,无法通过克隆参数隔离
    • 实例级 IAM 绑定(即 set-iam-policy 直接绑在实例上)会被克隆带走,必须显式清理
  3. 国内可落地的三条技术路径:
    • 路径 A:克隆后立刻执行 gcloud sql instances remove-iam-policy-binding,用脚本批量撤销;
    • 路径 B:在组织策略里启用 “iam.disableServiceAccountKeyCreation”+“iam.uniformBucketLevelAccess” 等约束,把高危角色直接禁止
    • 路径 C:采用 Terraform 蓝绿方案,克隆时把 deletion_protection=falseiam_policy=[] 写进 .tf,apply 时强制覆盖空绑定,实现 IaC 一次成型。
  4. 合规加分项:
    • 把清理动作接入国内云审计(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 绑定,并用组织策略+流水线保证无人为遗漏。

拓展思考

  1. 如果源实例用了云 IAM + 自建 DB 账号混合模式,克隆后还需手动删除 postgres/mysql.user 表中继承来的高权账号,否则会出现“IAM 清空了,但数据库内账号还能登录”的权限逃逸场景。
  2. 在国内多项目隔离场景下,可预置一条组织策略约束
    constraint: "constraints/sql.restrictPublicIp"
    
    强制所有克隆实例禁用公网 IP把 IAM 误继承带来的风险锁定在 VPC 内
  3. 未来 Google Cloud 若推出 “clone 时指定 --clear-iam-bindings” 参数,仍需保持脚本兜底,因为组织策略的生效范围可能滞后于项目加入,**“防御式编程”**才是国内金融级合规的常态。