Day 15 的 release workflow 由 todo-api-v* 或 todo-bff-v* tag 觸發,會驗證對應的服務、將 image 推到 GHCR,並輸出 digest。這樣我們知道 image 是從哪個 source commit 建出來的,但還沒決定要部署到 Staging 還是 Production。
如果讓 CI 直接部署,它就得取得叢集的寫入權限。只要 workflow 出錯,環境就可能跟著被改動;團隊也少了一次檢查「這個版本該不該進這個環境」的機會。
所以 CI 產出 image digest,部署流程再以 GitOps 設定變更提出建議。團隊 review 並合併後,Argo CD 才把變更同步到叢集。CI 不需要持有 kubeconfig,也不必執行 kubectl apply。目前 release workflow 只輸出 digest,尚未建立設定 Pull Request。
以下用 repo-app 代表應用程式原始碼、repo-config 代表環境設定。兩者是規劃中的分工,並非目前已建立的兩個 repository。CI 到 CD 交接的是 digest,不是 CI 直接部署叢集:
repo-app(CI:產出 image)
source commit
-> 建立並推送 todo-api-v* 或 todo-bff-v* release tag
-> tag 觸發 release workflow:驗證、建置並推送 GHCR
-> image digest(交給部署流程,不直接部署)
repo-config(GitOps CD:決定部署版本)
以 CI 產出的 digest,在暫時分支更新目標環境設定
-> Pull Request -> review -> 合併到受保護分支
-> Argo CD 讀取合併後的 revision 並同步資源
-> Kubernetes controller 執行 reconcile
這條流程將證據留在各自的交接點:
這也保留了 GitOps 的信任邊界。CI 可以建立 config Pull Request,但只有 Argo CD 的受限身分能將已核准的設定收斂到叢集。
假設要讓 todo-api 的 Staging 使用新的 image,設定變更應只改這個環境的 digest,不順手修改 Service、Ingress 或其他環境。審查 Pull Request 的人才能看清楚:這次要換哪個版本、影響哪個環境。Kustomize overlay 可以用來區分環境,但不是 CI 與 GitOps 交接的必要條件。
目前 Argo CD 的 Application 讀取的是原生 Kubernetes 資源設定,沒有同步 Microservice 資源;使用 GHCR image 的 Deployment 也仍指定 ghcr.io/yrw9281/it30-todo-api:0.1.0 這類 tag。專案尚未建立獨立的環境設定 repository、環境 overlay 或自動更新 digest 的 workflow。這裡說的是設定變更該如何審查,並非已經把 CI、Argo CD 與 Microservice CRD 串起來。
同一份 image 要部署到 Production,應建立只影響 Production 的另一筆設定變更。Staging 使用了這份 image,不等於 Production 已核准;兩個環境採用同一個 digest,仍應是清楚記錄的決策。
以下是交接流程需要的權限設計,不代表每個身分與設定儲存庫都已存在。最小權限不只是 workflow 裡的一行 permissions,還要分清楚誰能讀取或改動什麼:
| 身分 | 應有的能力 | 不應有的能力 |
|---|---|---|
| PR CI | 讀取 source、執行 test | 推送 image、寫入 config repository、寫入叢集 |
| Release CI | 讀取選定 source revision、推送指定 image、建立 config Pull Request | 直接合併 protected branch、寫入 Kubernetes |
| Config reviewer | 核准或拒絕環境變更 | 修改 image bytes、取得 GHCR push credential |
| Argo CD | 讀取已核准 config、在指定 Namespace 執行 reconcile |
修改 application source、寫入任意 cluster |
建立 config Pull Request 的身分應使用權限範圍明確、可輪替的 GitHub App installation token 或同等的短期憑證,不要將長期 Personal Access Token(PAT)放進 workflow secret。protected branch 也必須要求必要 checks 與 review;CI 能自動建立 Pull Request,不表示它可以自行將變更合併到 Production。
部署發生問題時,團隊應能從叢集一路往回找到交付來源:
Argo CD Application revision
-> config repository merge commit
-> image digest in environment configuration
-> CI run that emitted the digest
-> source commit and Pull Request
反過來,這條鏈也能回答某個 source commit 是否已進入 Production。只靠手動複製 tag,或以未記錄的 kubectl 操作跳過 Git,任一方向都會斷掉。緊急修復完成後同樣要回寫 Git;否則 Argo CD 的 self-heal 或環境重建可能覆蓋該修復。
source CI 綠燈不代表環境設定一定正確。設定 Pull Request 至少應驗證 YAML 能解析、image reference 屬於核准的 ghcr.io/yrw9281/ repository 且使用 digest 格式,並在不接觸 Production 的前提下驗證 Kubernetes schema。若採用 Kustomize,再檢查 render 的資源是否符合預期。
這些檢查處理的是不同層次的問題:Kustomize render 成功,不代表 Kubernetes API 一定接受;schema 驗證通過,也不代表 controller 已完成 reconcile,更不代表 workload 已健康。Production cluster 的寬鬆憑證不該只是為了方便驗證而交給 config check。
目前 CI 已能交出可追溯的 image,但 GitOps 設定變更與 Microservice CRD 尚未串接。下一篇會以 Backstage 作為開發者入口,說明內部開發者平台(Internal Developer Platform,IDP)預計如何經 Git、Argo CD 與 Operator 交付服務;這是控制流程的規劃,不是已完成的部署。