在 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/ abort the rollout)。在風險變更上線前進行驗證。 - 遷移是獨立、有序的管線步驟,可安全擴展(參見
zero-downtime-migrations),在依賴遷移的程式碼之前執行 — 絕不與需要新綱要的 Pod 捆綁在一起。 - CI 是閘道: lint、型別檢查、合約檢查、測試、安全掃描在每次變更時執行,並在
enforced模式下阻止合併。CI 同時建置映像檔並發布其來源證明,然後不經修改地提升該摘要。 - 開發/正式環境一致性與從環境取得設定。 來自 Azure Key Vault 的機密(透過 Secrets Store CSI 驅動程式或 sealed secrets)— 絕不放在映像檔或已提交的
.env檔案中。連接埠/設定來自環境變數。僅開發工具(pgTAP、測試執行器)絕不進入正式環境映像檔。
管線
| 層級 | 觸發器 | 環境 | 摘要 |
|---|---|---|---|
| 預覽 | PR 開啟 / 同步 | 臨時命名空間 preview-<app>-pr-<N> | 在此建置,標記為 sha-<pr-head> |
| 暫存 | 合併至 main | 持久命名空間 staging | 將預覽摘要重新標記為 sha-<merge> |
| 正式環境 | 發布版本發布 + 核准 | 命名空間 production | 發布提交之父 commit 的摘要 |
為何使用父 commit。 release-please 的發布提交僅變更 CHANGELOG.md 與 manifest,因此其樹狀結構並非暫存環境所浸泡過的內容—無論預覽為發布 PR 本身建置了什麼,都從未提升過預覽階段。其父 commit 是最後一個功能合併,正是暫存環境一直在驗證的內容,只要 release-please 將其發布分支保持在 main 的頂端(其預設行為)。從 Git 而非叢集即時狀態推導摘要,可保持提升的可重現性。
重新標記安全性。 Squash 合併會產生不同的提交 SHA,並且如果 main 在 PR 開啟期間移動過,則會產生不同的樹狀結構。兩個防護措施:
- 要求 "合併前分支必須為最新" — 這是必要狀態檢查規則的子集 — 因此 squash 樹狀結構透過建構與 PR 頭部樹狀結構相等。此防護需要分支保護,因此僅存在於
enforced模式中;處於advisory模式的專案將以下樹狀結構比較作為其唯一的防護,並應預期重新建置路徑是常規而非例外。 - 驗證而非假設:比較
git rev-parse <merge>^{tree}與 PR 頭部樹狀結構。相等 → 重新標記。不相等 → 在合併 SHA 上重新建置。這並非交付規則所禁止的逐環境重新建置:樹狀結構不相等表示內容本身與預覽階段驗證的內容不同,因此沒有可提升的成品可重複使用—而重新建置的映像檔以全新候選者的身份進入暫存環境,而非提升。請注意,當採取此路徑時會失去什麼:該映像檔從未在預覽環境中審查過,因此「已出貨的映像檔即是已審查的映像檔」對它不成立。暫存環境變成了它的第一個驗證,而非第二個。
重新標記是一個指標操作——無需重新建置,無需拉取:
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 環境 | 隔離命名空間,合併時銷毀 |
| 綱要 | 獨立的順序步驟,可安全擴展,在程式碼之前 |
| 提升 | 重新標記摘要;絕不為每個環境重新建置 |
| 核准 | 環境審查者(enforced)或手動分派(advisory) |
為何此處被隔離: 所有 Azure/k8s 特定內容都位於此處,由堆疊特定觸發器驅動。僅本機或不同雲端的專案會使用自己的交付技能;原則(不可變成品、可逆 + 漸進式部署、解耦的遷移)來自 resilience-and-deploy-safety。
完整理由:憲法第 XIX 條,收錄於 engineering-constitution/references/engineering-constitution.md。