基于AKS的云交付
概述
基于Kubernetes/Azure的交付机制。实现了AKS上的部署安全性和验证门控。按技术栈设计——该技能仅在任务涉及k8s/AKS时加载,因此没有云部署需求的项目(例如仅本地的Docker Compose)永远不会看到此内容。
交付规则
- 本地开发运行完整技术栈,通过Docker Compose,一条命令即可,全面——这是一等要求。
- 镜像在CI中构建 → GHCR,通过内容摘要标识,然后保持不变地提升:预览→暂存→生产。永不按环境重新构建。
- 每个PR的临时预览环境。 每个PR部署到AKS上自己独立的命名空间供审查,在合并/关闭时销毁。 集成测试环境;创建和销毁成本低廉。
- Kubernetes健康门控。 每个工作负载定义liveness、readiness和startup探针(连接到
observability-and-slos中的端点)、滚动更新策略(带有界定的maxUnavailable/maxSurge)以及PodDisruptionBudget。使用HPA进行负载管理。 - 面向生产的渐进式交付。 通过Argo Rollouts / Flagger实现金丝雀或蓝绿部署,并带有自动指标分析(关联SLO);失败的金丝雀自动中止。
- 回滚是一等公民且经过预演。 不可变、基于摘要寻址的镜像使回滚只需重新部署先前良好的摘要(
kubectl rollout undo/ 中止rollout)。在有风险的变更发布前进行验证。 - 迁移是独立的、有序的流水线步骤,可安全扩缩(参见
zero-downtime-migrations),在依赖它们的代码之前运行——绝不捆绑在需要新Schema的Pod中。 - CI是门控: lint、类型检查、契约检查、测试、安全扫描在每次变更时运行,并在
enforced模式下阻止合并。CI还构建镜像并发布其来源证明,然后将该摘要保持不变地提升。 - 开发/生产环境一致性与从环境获取配置。 来自Azure Key Vault的机密(通过Secrets Store CSI驱动或sealed secrets)——绝不放在镜像或提交的
.env文件中。端口/配置来自环境。仅在开发时使用的工具(如pgTAP、测试运行器)绝不出现在生产镜像中。
流水线
| 阶段 | 触发条件 | 环境 | 摘要 |
|---|---|---|---|
| preview | PR打开 / 同步 | 临时命名空间 preview-<app>-pr-<N> | 在此构建,标签为 sha-<pr-head> |
| staging | 合入main | 持久命名空间 staging | 将preview摘要重打标签为 sha-<merge> |
| production | 发布创建 + 审批 | 命名空间 production | 发布提交的父级摘要 |
为什么使用父级提交。 release-please的发布提交仅修改了CHANGELOG.md和清单文件,因此其树状结构从未被staging验证过——不论为发布PR构建的preview版本本身是什么,它从未被提升到preview之外。它的父级是最后一次功能合并,这正是staging一直在验证的内容,只要release-please将其发布分支保持在main的顶端(这是其默认行为)。从git(而非实时集群状态)中推导摘要可保持提升的可重复性。
重打标签的安全性。 Sqaash合并会产生不同的提交SHA,并且如果main在PR打开期间有变动,还会产生不同的树。两个保护措施:
- 要求**“合入前分支已同步”**——这是必需状态检查规则的一个子集——从而保证squash树与PR头树在结构上相同。此保护需要分支保护,因此仅存在于
enforced模式下;处于advisory模式的项目仅依赖下面的树比较作为唯一保护,应预期重建路径是常规而非例外情况。 - 验证而非假设:比较
git rev-parse <merge>^{tree}和PR头树。相等→重打标签。不相等→在合并SHA处重建。这并非交付规则所禁止的每环境重建:不等的树意味着内容本身与preview验证的不同,因此没有可提升的制品可供重用——并且重建的镜像作为新的候选者进入staging,而非提升。注意,当采用此路径时,失去了什么:该镜像从未在preview环境中被审查过,因此“已发布镜像即已审查镜像”不再成立。Staging是其第一次验证,而非第二次。
重打标签是一种指针操作——无需重建,无需拉取:
docker buildx imagetools create -t "$REPO:sha-$MERGE_SHA" "$REPO@sha256:$DIGEST"
证明仍绑定到PR头SHA,因此需在部署记录中记录头→合并的映射;镜像配置无法在不重建的情况下编辑。
审批门控——一个属性,两种机制:
| 模式 | 机制 |
|---|---|
enforced | GitHub环境 production,需要审查者 |
advisory | 一个 workflow_dispatch提升任务;运行它即是决策 |
快速参考
| 关注点 | 机制 |
|---|---|
| 机密 | Key Vault → CSI驱动;轮换;绝不在镜像中 |
| 健康 | liveness + readiness + startup探针;readiness检查真实依赖 |
| 安全发布 | 金丝雀/蓝绿,SLO门控,失败时自动中止 |
| 回滚 | 重新部署先前良好的摘要;有风险变更前预演 |
| 每个PR环境 | 独立命名空间,合并时销毁 |
| Schema | 独立有序步骤,安全扩缩,在代码之前 |
| 提升 | 重打标签摘要;永不按环境重建 |
| 审批 | 环境审查者(enforced)或手动调度(advisory) |
为何此技能被隔离: 所有Azure/k8s的细节都通过技术栈特定触发器存放在此处。仅本地或不同云项目的项目使用其自己的交付技能;而原则(不可变制品、可逆且渐进式部署、解耦迁移)来自resilience-and-deploy-safety。
完整原理:宪法第十九条,见 engineering-constitution/references/engineering-constitution.md。