如何避免自动关闭脚本误停生产实例?

解读

在国内金融、电商、政务云等场景,“自动关闭脚本”通常指基于标签、定时任务或成本治理平台(如阿里云“自动释放”、腾讯云“定时关机”、自研FinOps脚本)触发的批量关机/降配逻辑。Google Cloud SQL 虽为全托管,但实例状态仍可通过 gcloud、Terraform、Cloud Scheduler 或组织 Policy 被意外停止(例如把 activationPolicy=NEVER 当成“节省成本”手段)。一旦误停,跨区域高可用实例会触发故障转移,单区域实例则直接中断业务,且重新启动后 SLA 不赔偿。因此,面试核心不是“会不会停”,而是如何用 Google Cloud 原生机制与国内合规要求,构建多层“防呆”防线

知识点

  1. IAM 最小权限与条件属性:利用 resource.nameresource.labelsrequest.time 做**“拒绝停止生产”**组织级约束。
  2. 标签与命名规范“env:prod” 标签必须不可被实例管理员篡改,需绑定 IAM 条件 + Resource Manager 标签锁定。
  3. Cloud IAM Deny Policy(2023 正式 GA):对 cloudsql.instances.stopcloudsql.instances.deletecloudsql.instances.update 设置全局拒绝规则,优先级高于角色授权。
  4. Terraform 生命周期钩子:通过 lifecycle { prevent_destroy = true } + google_tags_location_tag_binding 保证CI/CD 管道无法销毁生产实例
  5. Policy Analyzer & Asset Inventory:每夜扫描**“谁可以 stop prod”,结果写入国内必须保留 180 天的日志审计桶**。
  6. Cloud Scheduler + Cloud Functions “双签”:关机脚本必须由两人分别提交 Secret Manager 版本,函数校验prod 标签 + 当前值班 on-call 名单后才可执行。
  7. Private Service Connect + VPC-SC 安全边界:把Cloud SQL Admin API 限定在专用网段,阻断公网临时凭证误调用。
  8. 预算与配额告警替代停机:利用Cloud Billing Budget API触发微信/飞书机器人,只告警不关机,符合国内“先审批后操作”合规流程。
  9. 多项目隔离生产项目只授权给 SRE 组,Dev/Staging 项目给研发,关闭脚本所在 SA 无任何生产项目 IAM
  10. Backstage/内部开发者平台模板禁止传入 activationPolicy=NEVER,模板渲染时自动为 prod 实例追加**“do-not-stop:true” 标签及对应 Deny Policy**。

答案

面对面试官,我会给出**“四层七防”**实战方案,既体现 Google Cloud 原生能力,也贴合国内监管与企业文化:

  1. 标签与命名层
    所有生产实例统一打上**“env:prod”“business:core”标签,并通过Resource Manager 的“标签锁定”功能**禁止后续修改;命名强制以 prod- 开头,方便脚本快速过滤。

  2. IAM 与组织策略层
    在组织节点创建IAM Deny Policy,明文拒绝任何主体对匹配 resource.matchTag('env','prod') 的实例执行 cloudsql.instances.stopcloudsql.instances.delete;同时移除项目 Owner 的 cloudsql.admin 角色,仅保留**“Cloud SQL Client”+“Viewer”给开发,停机权限收归SRE 专属自定义角色**。

  3. 自动化脚本层
    把关机逻辑封装进Cloud Functions Gen2,入口由Cloud Scheduler 每分钟轮询“成本标签”,但函数内部二次校验

    • 实例标签是否包含**“do-not-stop:true”**;
    • 当前时间是否在国内**“禁止变更窗口”**(如 0:00-06:00、双 11 大促、央行清算日);
    • 调用者必须在Secret Manager 中写入双人审批的 JSON 片段,函数用Cloud Audit Logs 校验两人身份
      任一条件不满足立即抛出 403 并@飞书值班群
  4. 审计与回滚层
    所有 cloudsql.instances.patch 调用默认写入国内合规日志桶(保留 180 天,加密密钥在中国 KMS 区域);每夜用**Policy Analyzer 导出“who can stop prod”报告,异常权限自动开 Jira 工单,限期 24h 回收。万一误停,利用 Point-in-Time Recovery 与 跨区域热备实例RTO < 5 分钟,并触发“P1 故障”**复盘流程。

通过**“标签锁定→Deny Policy→双签函数→审计复盘”四道闸门,100% 阻断自动脚本误停生产实例,同时满足等保 2.0 对“运维操作审批”与“日志留存”**的刚性要求。

拓展思考

  1. 如果公司混合云还有线下 MySQL,如何统一**“防误停”策略?
    答:可
    把线下实例录入 Google Cloud Asset Inventory 的“非 Google 资源”,用Terraform 的 external data source同步标签,Deny Policy 虽不适用,但可在自研平台调用“工单系统 API”实现双人审批,形成“云上云下同一套标签+审批”

  2. FinOps 团队坚持“夜间关机省 30% 成本”,如何说服?
    答:Google Cloud SQL 按秒计费但磁盘持续收费,关机节省的 CPU/RAM 费用不足 15%,却带来可用性降级与 SLA 失效;应改用共享 CPU 实例(db-f1-micro→db-g1-small)或 Commitment + 弹性池既省钱又不中断,用成本报告量化对比即可。

  3. Terraform 1.6 引入“import block”,如何防止导入时把 prod 实例误销毁?
    答:在CI Pipeline 里强制加 terraform plan -out=tfplan && terraform show -json tfplan | jq -r '.resource_changes[] | select(.change.actions[] | contains("delete")) | .address' | grep google_sql_database_instance | xargs -I {} echo "ERROR: trying to delete {}" && exit 1任何删除动作直接阻断 MR,实现**“代码级防呆”**。

  4. 国内多云灾备场景,若使用Cloud SQL for SQL Server 的跨区域只读副本做灾备,停止主实例前如何确保副本已提升?
    答:在双签函数中先调用 gcloud sql instances promote-replica <read-replica-name> --project=<dr-project>等待 replicaName.promoteOperation.status=DONE 后,再停止原主实例,并自动更新内网 DNS 指向新主,实现**“先提升后停机”,保证业务连续性与数据零丢失**。