4. 跨云资源编排与基础设施即代码
当基础设施即代码(IaC)从单云单账号扩展到多云生产环境后,真正困难的往往不再是“如何声明一台虚拟机”,而是状态(State)如何被可信地保存、漂移(Drift)如何被及时发现、变更失败后如何安全回滚。Terraform、Pulumi、Crossplane 都能完成跨云资源编排,但它们对状态、漂移和回滚的处理模型差异很大,选型时必须先看清这一点。
三种工具的状态模型差异
Terraform 采用显式的状态文件(terraform.tfstate)。状态文件记录了“声明资源”与“真实资源 ID”的映射,是 plan 计算差异的唯一依据。生产上必须使用远端后端(如 S3 + DynamoDB 锁、Terraform Cloud、OSS + Tablestore),并开启状态锁与版本控制。状态一旦丢失或被人为编辑,plan 结果就不可信。
Pulumi 的状态由 Pulumi Service 或自建后端(如 S3、Azure Blob)托管,状态中保存资源 URN、输入输出与依赖关系。它用真实编程语言表达基础设施,因此状态与代码的耦合更紧,但同样存在“状态与真实资源不一致”的风险。
Crossplane 的思路不同:它把状态放在 Kubernetes 的 etcd 中,通过 Provider 持续调谐(Reconcile)期望状态与实际状态。它不是“一次性 apply”,而是持续控制循环,因此漂移检测天然内建,但代价是控制面复杂度更高。
漂移检测:从“事后发现”到“持续发现”
漂移指真实云资源被控制台手工修改、被其他自动化工具改动,或云厂商侧发生变更,导致与 IaC 声明不一致。Terraform 和 Pulumi 属于触发式检测:只有执行 plan/preview 或 refresh 时才会对比。生产上应把 plan 纳入 CI,每日定时对关键 stack 执行一次只读 plan,并把“非空 diff”作为告警。
Crossplane 属于持续检测:控制器每隔一段时间(默认约 1 分钟,可配置)拉取实际状态并与期望状态比较,发现偏差后自动尝试纠偏。这带来一个关键区别:如果有人在云控制台手工改了安全组,Crossplane 会把它改回去;而 Terraform 只会在下次 apply 时覆盖。因此使用 Crossplane 时,必须明确哪些资源允许“被自动纠偏”,哪些应设为观察模式,避免误改生产配置。
回滚策略:状态回滚与资源回滚是两件事
很多人把“回滚”简单理解为“把代码改回去再 apply”,但在多云生产中这不够。回滚需要同时考虑状态文件/状态记录和真实资源两个层面。
对 Terraform,推荐做法是:每次 apply 前把远端 state 复制一份带时间戳的备份;apply 失败或结果异常时,先恢复旧 state,再执行 plan 确认差异,最后决定是重新 apply 还是手工修复资源。注意:直接回滚 state 不会自动回滚真实资源,必须配合 plan 判断。
对 Pulumi,可以利用 stack 历史版本回退到上一个成功版本,再执行 up。Pulumi 会基于回退后的状态重新计算差异,因此比手工改 state 更安全。
对 Crossplane,回滚通常通过 Git 回退实现:把 Composition 或 Claim 的期望状态改回旧版本,控制器会自动调谐回旧配置。但要注意,某些云资源(如已创建的数据库)不会因为期望状态回退而被删除,需要显式处理保留策略。
多云生产中的落地建议
第一,状态隔离:按云厂商、账号、环境、区域四个维度隔离状态,避免一个 state 横跨多个云导致爆炸半径过大。第二,变更可审计:所有 IaC 变更走 Git PR,plan 结果作为评审材料,apply 由 CI 执行并记录操作者与版本。第三,漂移告警:Terraform/Pulumi 每日定时 plan,Crossplane 监控 Reconcile 失败与资源不健康状态。第四,回滚演练:定期在预发环境演练 state 恢复与 Git 回退,确认回滚路径真实可用,而不是只写在文档里。
最后,三种工具并非互斥。常见组合是:用 Terraform 管理云账号、网络、IAM 等低频基础资源;用 Pulumi 管理需要编程逻辑的应用基础设施;用 Crossplane 在 Kubernetes 内提供自助式资源申请与持续纠偏。关键是统一状态管理规范、统一漂移检测口径、统一回滚演练机制,让多云编排从“能跑”走向“可信”。