Docker + K8s CI/CD 自動化流水線
到目前為止,我們學會了 Docker 容器化、Docker Compose、Kubernetes 部署與監控。但每次更新版本時,如果都要手動執行 docker build、docker push、kubectl apply,不僅麻煩而且容易出錯。
CI/CD (Continuous Integration / Continuous Deployment) 就是為了解決這個問題而生。它讓你的部署流程完全自動化:
- 開發者推送程式碼到 GitHub
- 自動觸發建置流程
- 自動執行測試
- 自動建置 Docker Image 並推送到 Container Registry
- 自動更新 Kubernetes 叢集上的部署
整個過程完全不需要人工介入!
CI/CD 架構總覽
開發者推送程式碼到 GitHub
│
▼
GitHub Actions 自動觸發
│
├── 1. Checkout 程式碼
├── 2. 執行 ESLint / 單元測試
├── 3. 建置 Docker Image
├── 4. 推送 Image 到 Container Registry (Docker Hub / GHCR)
├── 5. 更新 Kubernetes 部署 YAML 中的 Image Tag
└── 6. kubectl apply 部署到 K8s 叢集
│
▼
Kubernetes 自動滾動更新
第一步:建立 Container Registry
Container Registry 是存放 Docker Image 的地方,類似 GitHub 但專門存放容器映像檔。以下是常見的選擇:
| Registry | 價格 | 說明 | |----------|------|------| | Docker Hub | 免費 1 個私有 Repository | 最普及,但免費方案有限制 | | GitHub Container Registry (GHCR) | 免費、無限制 | 🏆 推薦,與 GitHub Actions 完美整合 | | Google Artifact Registry | 付費 | GCP 使用者專用 |
我們使用 GitHub Container Registry (GHCR),因為它完全免費且與 GitHub Actions 無縫整合。
手動推送一次 Image(測試)
# 建立 Image 並標記為 GHCR 格式
# 格式:ghcr.io/<你的 GitHub 帳號>/<Image 名稱>:<版本>
docker build -t ghcr.io/your-username/my-app:latest .
# 登入 GHCR
echo $GITHUB_TOKEN | docker login ghcr.io -u your-username --password-stdin
# 推送 Image
docker push ghcr.io/your-username/my-app:latest
第二步:建立 GitHub Actions Workflow
在專案中建立 .github/workflows/deploy.yml:
name: Build & Deploy to K8s
on:
push:
branches:
- main # 只有推送到 main 分支才觸發
- develop # 推送到 develop 也觸發(但不部署到正式)
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
# === Job 1:測試與建置 ===
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write # 需要寫入 GHCR 的權限
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linting
run: npm run lint
- name: Run tests
run: npm test
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
# === Job 2:部署到 Kubernetes ===
deploy:
needs: build # 等待 build Job 完成
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' # 只在 main 分支部署
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup kubectl
uses: azure/setup-kubectl@v4
with:
version: 'v1.28.3'
- name: Configure K8s context
uses: azure/k8s-set-context@v4
with:
kubeconfig: ${{ secrets.KUBECONFIG }}
- name: Update image tag in deployment YAML
run: |
# 使用 sed 將 YAML 中的 Image Tag 更新為當前 Commit SHA
sed -i "s|image:.*|image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}|" k8s/deployment.yaml
- name: Deploy to Kubernetes
run: |
kubectl apply -f k8s/
kubectl rollout status deployment/frontend --timeout=5m
kubectl rollout status deployment/backend --timeout=5m
Workflow 解析
觸發條件 (on)
- 只有當
main或develop分支有推送時才觸發 - 你可以根據需求設定不同的觸發條件(例如只針對特定路徑的變動)
Job 1:build
- 檢出程式碼
- 安裝 Node.js 並快取套件
- 安裝相依套件 (
npm ci) - 執行 Lint 檢查
- 執行測試
- 登入 GHCR
- 建置 Docker Image 並推送(同時推送
latest和commit SHA兩個標籤)
Job 2:deploy
- 等待 build 成功
- 設定 kubectl
- 設定 K8s 連線資訊(使用 KUBECONFIG Secret)
- 更新部署 YAML 中的 Image 版本
- 部署到 K8s 並監控滾動更新狀態
第三步:設定 GitHub Secrets
為了安全起見,我們不應該將 K8s 連線資訊直接寫在程式碼中。請到 GitHub Repository 的 Settings → Secrets and variables → Actions 新增以下 Secret:
| Secret 名稱 | 說明 | 取得方式 |
|------------|------|---------|
| KUBECONFIG | K8s 叢集的 kubeconfig 檔案內容 | 從你的 .kube/config 複製,或是從雲端服務商下載 |
取得 KUBECONFIG
# DigitalOcean
doctl kubernetes cluster kubeconfig show my-cluster
# 或是直接查看本機的 kubeconfig
cat ~/.kube/config
# 複製內容後貼到 GitHub Secrets 中
⚠️ 安全提醒:Kubeconfig 包含了叢集的管理員憑證,請絕對不要將它提交到 GitHub Repository 中!一定要使用 GitHub Secrets。
第四步:進階 CI/CD 技巧
1. 多環境部署(Staging / Production)
你可以設定兩個 Workflow,分別部署到測試與正式環境:
on:
push:
branches:
- develop # 自動部署到 Staging
- main # 自動部署到 Production
在 Workflow 中根據分支名稱動態切換 K8s 設定檔。
2. Database Migration 自動化
在部署新版本之前,自動執行資料庫 Migration:
- name: Run database migration
run: |
kubectl exec deployment/backend -- alembic upgrade head
3. 自動 Rollback(部署失敗時)
如果滾動更新失敗,自動回滾到上一個版本:
- name: Deploy to Kubernetes
run: |
kubectl apply -f k8s/ || \
(echo "Deployment failed, rolling back..." && \
kubectl rollout undo deployment/frontend && \
exit 1)
完整 CI/CD 流程實戰演練
現在,讓我們實際跑一遍完整的 CI/CD 流程:
本地端
# 1. 開發新功能
git checkout -b feature/new-api
# 2. 修改程式碼...
# 3. 提交並推送
git add .
git commit -m "feat: add new API endpoint"
git push origin feature/new-api
GitHub Actions 自動執行
推送後,前往 GitHub Repository 的 Actions 頁面,你會看到一個新的 Workflow 正在執行。點擊進入可以看到即時的執行日誌。
驗證部署
# 當 Workflow 完成後,檢查 K8s 部署狀態
kubectl get pods
kubectl rollout status deployment/frontend
# 檢查新版本是否正確運行
kubectl logs -f -l app=frontend
使用 Vibe Coding 生成 CI/CD Workflow
不用背 YAML 語法!讓 AI 幫你產生:
**🔥 【CI/CD Workflow 詠唱範例】 **
「請幫我產生一個 GitHub Actions Workflow:1. 當推送到 main 或 develop 分支時觸發。2. 使用 Node.js 20 進行 npm ci、lint 與 test。3. 建置 Docker Image 並推送到 ghcr.io。4. 使用 Image Tag 為 github.sha 與 latest。5. 使用 kubectl 部署到 K8s,kubeconfig 從 GitHub Secrets 讀取。6. 部署前先更新 deployment YAML 中的 Image Tag。7. 部署後執行 kubectl rollout status 等待部署完成。8. 加上超時設定與錯誤處理 (rollback)。」
本日總結
在本章中,你學到了:
- ✅ CI/CD 核心概念:從程式碼提交到自動部署的完整流程
- ✅ Container Registry:使用 GHCR 免費存放 Docker Image
- ✅ GitHub Actions Workflow:完整的 build → push → deploy 流水線
- ✅ GitHub Secrets:安全地管理 K8s 連線資訊
- ✅ 多環境部署:Staging / Production 分離
- ✅ 自動 Rollback:部署失敗時自動復原
- ✅ Vibe Coding 生成技巧:用自然語言描述 CI/CD 需求
恭喜你完成了整個 Docker & Kubernetes 雲端部署實戰 課程!你現在已經具備了將任何應用容器化、部署到雲端 K8s 叢集、設定監控與自動伸縮、以及建立自動化 CI/CD 流水線的完整能力。
這些技能在市場上具有極高的價值,無論是提升接案報價、求職 DevOps 工程師,或是經營自己的 SaaS 產品,都能讓你擁有巨大的競爭優勢!