弹性与部署安全 是做什么的?
概述
事情总会出错。立场不是“防止所有失败”,而是小故障、快恢复、每次学习。 可靠性不是没有失败,而是当失败发生时,爆炸半径可控且恢复时间短。
部署安全——每次部署都可逆且渐进式暴露
- 制品是不可变的,且通过晋升而非重建。 一个镜像,在 CI 中构建一次并由其内容摘要标识,不变地在预览→预发布→生产环境中移动。为每个环境重建意味着部署你从未测试过的东西。
- 标签是可变的指针;摘要是身份。 标签可以被覆盖,静默地指向新位置。内容摘要不能。每个环境记录它验证过的摘要,生产环境只运行已被较低环境验证过的摘要——因此“我们测试过的确切东西”是流水线强制执行的属性,而非需要某人记住的纪律。
- 部署到生产前需要人为决策。 对于单个维护者,这指的是有意的暂停和审计记录,而非职责分离。请明确具体是哪种情况;不要过度宣传。
- 运行中的版本在部署时注入,从不内嵌到镜像中。 作为构建参数内嵌的版本强制重建以标记发布,而重建恰恰是晋升要避免的。
- 当基础设施独立存在于自己的仓库时,通过扩展/收缩协调。 基础设施先扩展(增量的、向后兼容的),应用程序在后续部署中消耗新能力,只有当没有活跃制品依赖旧结构时基础设施才收缩——这与数据库模式变更的纪律相同(参见
零停机迁移)。不变条件:绝不交付需要尚未上线的基础设施变更的应用制品。 遵循此条件,每个仓库独立可逆,这使两者不同步时回滚可行。 - 只有能回滚时才向前滚动。 回滚路径在风险变更上线前就已存在并经过测试。“我们如何撤销这个?”在计划中回答,而非在事件中。
- 回滚即重新部署之前良好的摘要。 该摘要仍存在于注册表中且不可变,因此回滚是反向晋升——绝不重建,也绝不“按原样”重建。
- 渐进式暴露。 新版本逐渐到达用户(健康检查门控的金丝雀部署,若支持),因此不良发布只影响一小部分,而非所有人。
- 模式变更与代码部署解耦,遵循扩展/收缩模式(参见
零停机迁移)。部署绝不能要求同时进行破坏性迁移。 - 部署就绪检查清单门控生产: 可观测性到位、回滚已验证、迁移扩展安全、SLO 无中断。
事件响应——失败是学习的输入
- 按严重级别分类并相应响应;有已知路径联系合适的人。
- 对每个面向用户的事件进行无指责事后审查。 书面时间线、促成原因(系统性的,非个人的)、具体行动项。问题是“系统哪方面导致了这事”,从不问“谁搞砸了”。
- 行动项被追踪,而非遗忘——它们流入未来考量文档(参见
记录决策)并成为实际工作。 - 错误预算主导。 当可靠性已耗尽时,可靠性工作优先级高于功能,直至预算恢复。
快速参考
| 风险部署前 | 确认项 |
|---|---|
| 制品 | 在 CI 中构建一次;通过摘要晋升;预发布验证的同一个 |
| 门控 | 部署到生产前记录人为决策 |
| 回滚 | 路径存在且已验证 |
| 暴露 | 渐进式/金丝雀,而非一次性全部 |
| 模式 | 扩展安全,与代码部署解耦 |
| 可观测性 | 你能看到是否出错吗? |
何时扩展此实践
本地/预启动项目现在编写这些规则,在第一批真实用户时启用。这些属性是可移植的——构建一次、晋升已验证内容、上线前决策、能够回滚——但机制并非如此:摘要晋升在容器主机上有意义,但对静态站点基本无关;托管平台可能免费提供预览环境和即时回滚。在项目交付技能中命名具体机制;此处保持属性。组合机制(k8s 探针、金丝雀、每个 PR 环境):cloud-delivery-aks。
完整原理:宪法第十二条,打包在 engineering-constitution/references/engineering-constitution.md 中。