CI/CD 十關|說明文件

GitLab CI/CD 教學專案

GitLab CI/CD 十關

從第一條 pipeline 一路做到 k8s 實機部署。每一關一個資料夾,裡面有說明與可以直接執行的 .gitlab-ci.yml。Lv.1~Lv.9 在 gitlab.com 共享 runner 實跑通過;Lv.10 用正式網站同一套流水線,把課程網站建成映像、簽章,經 GitOps 部署到 homelab k8s。

十關目錄

關卡主題類型你會學到
Lv.1第一條 Pipeline基礎pipeline、job、runner 的關係;image、script
Lv.2Stages 與 Jobs基礎stages 順序、平行 job、default、before/after_script、allow_failure 指定結束碼、.pre/.post
Lv.3Artifacts基礎產物傳遞、expire_in、dependencies、JUnit 測試報告
Lv.4Variables基礎內建變數、覆寫順序、手動執行表單、dotenv 在 job 間傳值、機密要放 Masked+Protected
Lv.5Cache進階cache key 依相依清單計算、policy: pull、extends、cache 與 artifacts 的分工
Lv.6Rules 與 workflow進階workflow 避免重複 pipeline、rules:if/changes/exists、manual、delayed、never
Lv.7Needs 與 DAG進階needs 縮短 pipeline、needs 決定下載哪些產物、parallel:matrix、!reference
Lv.8Services進階Redis、PostgreSQL 整合測試、alias、等待服務就緒、entrypoint 覆寫
Lv.9Environments進階review app、on_stop、auto_stop_in、resource_group、手動上 production、Rollback
Lv.10實機部署到 k8s實機Harbor、Trivy、cosign、Kyverno、GitOps、Argo CD、Envoy Gateway、cert-manager

每關的說明在各資料夾的 README.md,課程網站上每關一頁,含完整範例檔與複製按鈕。

技術棧

領域工具用途
CIGitLab CI/CDLv.1~Lv.9 用 gitlab.com 共享 runner;Lv.10 用 homelab 的 k8s-ci(掃描,沒有密鑰)與 k8s-release(只收受保護分支)
安全掃描gitleaks、Trivy、Semgrep機密、相依套件與映像漏洞(有修補版的 CRITICAL 就擋)、程式寫法;映像產生 SBOM
建置BuildKit無 root 建置映像
映像倉庫Harborsites/cicd-tutorial
供應鏈cosign+Kyverno傳統 .sig 簽章,叢集准入時驗章
部署Argo CD(GitOps)以 homelab-k8s repo 的 apps/cicd-tutorial/values.yaml 為準
入口Envoy Gateway共用 Gateway,本站獨立 HTTPRoute;HSTS、壓縮、上傳上限 1Mi
憑證cert-managerLet's Encrypt HTTP-01,自動續期
網站Python 標準函式庫、nginx-unprivileged把各關 README 轉成靜態網頁;容器內 nginx 只送檔,非 root
前端原生 HTML/CSS/JavaScript卡片拖拉+群組(滑鼠、觸控長按、鍵盤)、深淺色、RWD,CSP 不允許 inline 腳本

部署方式

push 到 main(受保護分支)後自動部署,不手動操作主機:

  1. 掃描:gitleaks、Trivy、Semgrep;同時 site-check 把網站產生一次並檢查。
  2. 建置映像:BuildKit 依 lv10-k8s-deploy/Dockerfile 建置,推上 Harbor,標籤是 commit 前 8 碼。
  3. 映像檢查:Trivy 掃描、產生 SBOM。
  4. 簽章:cosign 傳統 .sig 格式。
  5. 更新 GitOps:CI 把新標籤寫進 homelab-k8s 的 apps/cicd-tutorial/values.yaml。
  6. Argo CD 同步:約 3 分鐘內滾動更新 site-cicd-tutorial,Kyverno 驗章通過才會啟動。
  7. 對外:Envoy Gateway listener https-cicd-tutorial-yc-group-org,cert-manager 簽發憑證。
網域cicd-tutorial.yc-group.org(需要 DNS A 紀錄指到主機公網 IP)
namespacesite-cicd-tutorial(Pod Security restricted、預設拒絕網路)
Deploymentcicd-tutorial-web,容器 8080,滾動更新不中斷
Argo CDsite-cicd-tutorial(由 ApplicationSet 依 apps/ 目錄自動產生)
回復在 homelab-k8s git revert CI 的部署 commit,Argo CD 自動換回舊版

驗證:

kubectl -n site-cicd-tutorial get pods
kubectl -n site-cicd-tutorial get httproute cicd-tutorial -o jsonpath='{.status.parents[0].conditions}'
kubectl -n argocd get application site-cicd-tutorial -o jsonpath='{.status.sync.status} {.status.health.status}'
curl --resolve cicd-tutorial.yc-group.org:443:10.10.10.50 -I https://cicd-tutorial.yc-group.org/

2026-11-09 17:39 已上線:DNS(HiNet A → 114.32.115.113)生效後把網域加進 Envoy 的 hosts,Let's Encrypt 憑證約 20 秒簽好;Gateway、HTTPRoute、Argo CD 都正常。沒有 DNS 就先加 hosts 會讓共用 Gateway Degraded,這次第一次上線時實際發生過,已改正。

本機預覽:python3 lv10-k8s-deploy/site/build.py --out /tmp/cicd-site,再用 python3 -m http.server -d /tmp/cicd-site 8000 開啟。預覽完記得關掉。

更新紀錄