目錄
- 什麼是 CI/CD?
- 核心概念
- CI/CD 流程階段
- 常見 CI/CD 工具
- Pipeline 設計
- GitHub Actions 實戰
- GitLab CI/CD 實戰
- Jenkins 實戰
- 部署策略
- 最佳實踐
- 常見問題
- 總結
什麼是 CI/CD?
CI - 持續整合(Continuous Integration)
持續整合是開發人員頻繁將程式碼變更合併到主分支的實踐,每次合併都會觸發自動化建構和測試。
開發者提交 → 自動建構 → 自動測試 → 回饋結果
↓ ↓ ↓ ↓
git push compile unit test pass/fail
核心目標:
- 儘早發現整合問題
- 減少手動測試時間
- 確保程式碼品質
CD - 持續交付/持續部署
| 術語 | 英文 | 說明 |
|---|---|---|
| 持續交付 | Continuous Delivery | 自動化到「準備部署」階段,但需人工批准才部署到生產環境 |
| 持續部署 | Continuous Deployment | 完全自動化,通過所有測試後自動部署到生產環境 |
持續交付:
程式碼 → 建構 → 測試 → Staging → [人工批准] → Production
持續部署:
程式碼 → 建構 → 測試 → Staging → Production(全自動)
CI/CD 完整流程圖
核心概念
Pipeline(流水線)
Pipeline 是 CI/CD 的核心,定義了從程式碼到部署的自動化流程。
# Pipeline 基本結構
pipeline:
stages:
- build # 階段 1:建構
- test # 階段 2:測試
- deploy # 階段 3:部署
jobs:
build-job: # 工作 1
stage: build
steps: [...]
test-job: # 工作 2
stage: test
steps: [...]
Stage(階段)
階段是 Pipeline 的邏輯分組,同一階段的工作可並行執行。
Stage 1: Build Stage 2: Test Stage 3: Deploy
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ compile │ │ unit-test │ │ staging │
│ package │ → │ integration │ → │ production │
│ docker-build│ │ e2e-test │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
串行 並行 串行
Job(工作)
Job 是實際執行的任務單元,包含一系列步驟。
job-name:
stage: build
image: node:18 # 執行環境
script: # 執行步驟
- npm install
- npm run build
artifacts: # 產出物
paths:
- dist/
Artifact(產出物)
Artifact 是 Job 產生的檔案,可傳遞給後續階段使用。
| 類型 | 說明 | 範例 |
|---|---|---|
| 建構產物 | 編譯後的程式 | dist/、build/、.jar |
| 測試報告 | 測試結果檔案 | coverage/、test-results.xml |
| Docker 映像 | 容器映像 | myapp:latest |
| 部署包 | 可部署的封裝 | release.tar.gz |
Runner/Agent
Runner 是執行 Pipeline 的實際機器或環境。
| 工具 | Runner 名稱 | 類型 |
|---|---|---|
| GitHub Actions | GitHub-hosted / Self-hosted | Runner |
| GitLab CI | GitLab Runner | Runner |
| Jenkins | Agent/Node | Agent |
| Azure DevOps | Microsoft-hosted / Self-hosted | Agent |
CI/CD 流程階段
1. Source(原始碼階段)
# 觸發條件設定
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
常見觸發方式:
- Push 到特定分支
- Pull Request 建立/更新
- 定時排程(Cron)
- 手動觸發
- Tag 建立
2. Build(建構階段)
build:
steps:
# 程式碼檢查
- name: Lint
run: npm run lint
# 編譯
- name: Compile
run: npm run build
# 建構 Docker 映像
- name: Docker Build
run: docker build -t myapp:${{ github.sha }} .
建構階段任務:
| 任務 | 說明 | 工具範例 |
|---|---|---|
| Lint | 程式碼風格檢查 | ESLint、Pylint、golangci-lint |
| Compile | 編譯程式碼 | tsc、javac、go build |
| Package | 打包應用 | webpack、Maven、Gradle |
| Docker Build | 建構容器映像 | Docker、Buildah、Kaniko |
3. Test(測試階段)
test:
parallel:
# 單元測試
- name: Unit Tests
run: npm run test:unit
coverage: true
# 整合測試
- name: Integration Tests
run: npm run test:integration
services:
- postgres:14
- redis:7
# E2E 測試
- name: E2E Tests
run: npm run test:e2e
測試類型金字塔:
╱╲
╱ ╲
╱ E2E╲ 少量、慢、高成本
╱───────╲
╱ ╲
╱Integration╲ 中等數量
╱─────────────╲
╱ ╲
╱ Unit Tests ╲ 大量、快、低成本
╱───────────────────╲
| 測試類型 | 範圍 | 速度 | 數量 |
|---|---|---|---|
| Unit | 單一函數/類別 | 快(毫秒) | 多(70%) |
| Integration | 多個元件互動 | 中(秒) | 中(20%) |
| E2E | 完整系統流程 | 慢(分鐘) | 少(10%) |
4. Security(安全掃描階段)
security:
steps:
# 依賴漏洞掃描
- name: Dependency Scan
run: npm audit --audit-level=high
# 靜態程式碼分析
- name: SAST
uses: github/codeql-action/analyze@v2
# 容器映像掃描
- name: Container Scan
run: trivy image myapp:latest
# 密鑰掃描
- name: Secret Scan
uses: trufflesecurity/trufflehog@v3
安全掃描類型:
| 類型 | 全名 | 說明 | 工具 |
|---|---|---|---|
| SCA | Software Composition Analysis | 依賴漏洞掃描 | npm audit、Snyk、OWASP |
| SAST | Static Application Security Testing | 靜態程式碼分析 | CodeQL、SonarQube、Semgrep |
| DAST | Dynamic Application Security Testing | 動態安全測試 | OWASP ZAP、Burp Suite |
| Container | Container Image Scanning | 容器映像掃描 | Trivy、Clair、Anchore |
5. Deploy(部署階段)
deploy:
stages:
# 部署到 Staging
- name: Deploy to Staging
environment: staging
script:
- kubectl apply -f k8s/staging/
# 部署到 Production(需審核)
- name: Deploy to Production
environment: production
when: manual # 手動觸發
script:
- kubectl apply -f k8s/production/
6. Monitor(監控階段)
post-deploy:
steps:
# 健康檢查
- name: Health Check
run: |
for i in {1..10}; do
curl -f https://app.example.com/health && exit 0
sleep 10
done
exit 1
# 通知
- name: Notify
uses: slack-notify-action
with:
status: ${{ job.status }}
常見 CI/CD 工具
工具比較表
| 工具 | 類型 | 託管方式 | 特點 | 適用場景 |
|---|---|---|---|---|
| GitHub Actions | SaaS | 雲端/自架 | 與 GitHub 深度整合 | GitHub 專案 |
| GitLab CI/CD | SaaS/自架 | 雲端/自架 | 功能完整、一站式 | GitLab 專案 |
| Jenkins | 自架 | 自架 | 高度可自訂、插件豐富 | 企業內部 |
| CircleCI | SaaS | 雲端 | 快速、易用 | 中小型專案 |
| Travis CI | SaaS | 雲端 | 開源專案友好 | 開源專案 |
| Azure DevOps | SaaS | 雲端/自架 | 微軟生態整合 | Azure 專案 |
| Argo CD | 自架 | K8s | GitOps、K8s 原生 | K8s 部署 |
| Tekton | 自架 | K8s | 雲原生、可擴展 | K8s 環境 |
選擇建議
你的程式碼在哪?
│
├─ GitHub → GitHub Actions(首選)
│
├─ GitLab → GitLab CI/CD(首選)
│
├─ 企業內部 Git
│ ├─ 需要高度自訂 → Jenkins
│ └─ 使用 K8s → Argo CD / Tekton
│
└─ 多平台/多雲 → Jenkins / CircleCI
Pipeline 設計
基本 Pipeline 結構
# 最小可行 Pipeline
stages:
- build
- test
- deploy
build:
stage: build
script:
- npm install
- npm run build
test:
stage: test
script:
- npm test
deploy:
stage: deploy
script:
- deploy.sh
only:
- main
進階 Pipeline 模式
1. 平行執行
test:
parallel:
matrix:
- NODE_VERSION: ['16', '18', '20']
OS: ['ubuntu-latest', 'windows-latest']
script:
- npm test
2. 條件執行
deploy-production:
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
- if: $CI_COMMIT_TAG
when: on_success
3. 快取策略
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .npm/
4. 多環境部署
.deploy-template: &deploy
script:
- kubectl apply -f k8s/${ENVIRONMENT}/
deploy-staging:
<<: *deploy
variables:
ENVIRONMENT: staging
environment:
name: staging
deploy-production:
<<: *deploy
variables:
ENVIRONMENT: production
environment:
name: production
when: manual
GitHub Actions 實戰
基本配置
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
NODE_VERSION: '18'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
- name: Build
run: npm run build
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: build
path: dist/
test:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- run: npm ci
- name: Run tests
run: npm test -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v3
deploy:
needs: [build, test]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
environment: production
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: build
- name: Deploy to production
run: |
echo "Deploying to production..."
# 部署腳本
Docker 建構與推送
# .github/workflows/docker.yml
name: Docker Build
on:
push:
branches: [main]
tags: ['v*']
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: myorg/myapp
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=sha
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
Kubernetes 部署
# .github/workflows/deploy-k8s.yml
name: Deploy to Kubernetes
on:
workflow_run:
workflows: ["Docker Build"]
types: [completed]
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@v4
- name: Configure kubectl
uses: azure/k8s-set-context@v3
with:
kubeconfig: ${{ secrets.KUBE_CONFIG }}
- name: Deploy
run: |
kubectl set image deployment/myapp \
myapp=myorg/myapp:sha-${{ github.sha }}
kubectl rollout status deployment/myapp
GitLab CI/CD 實戰
基本配置
# .gitlab-ci.yml
stages:
- build
- test
- security
- deploy
variables:
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
# 建構階段
build:
stage: build
image: node:18
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
# 測試階段
test:unit:
stage: test
image: node:18
script:
- npm ci
- npm run test:unit
coverage: '/Statements\s+:\s+(\d+\.?\d*)%/'
artifacts:
reports:
junit: junit.xml
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
test:integration:
stage: test
image: node:18
services:
- postgres:14
- redis:7
variables:
POSTGRES_DB: test
POSTGRES_USER: test
POSTGRES_PASSWORD: test
script:
- npm ci
- npm run test:integration
# 安全掃描
security:sast:
stage: security
image: returntocorp/semgrep
script:
- semgrep --config=auto --json -o semgrep.json .
artifacts:
reports:
sast: semgrep.json
security:dependency:
stage: security
image: node:18
script:
- npm audit --audit-level=high
allow_failure: true
# Docker 建構
docker:build:
stage: build
image: docker:24
services:
- docker:24-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $DOCKER_IMAGE .
- docker push $DOCKER_IMAGE
# 部署階段
deploy:staging:
stage: deploy
image: bitnami/kubectl:latest
environment:
name: staging
url: https://staging.example.com
script:
- kubectl config set-cluster k8s --server=$KUBE_SERVER
- kubectl set image deployment/myapp myapp=$DOCKER_IMAGE
only:
- develop
deploy:production:
stage: deploy
image: bitnami/kubectl:latest
environment:
name: production
url: https://example.com
script:
- kubectl set image deployment/myapp myapp=$DOCKER_IMAGE
when: manual
only:
- main
GitLab CI 特殊功能
# 動態環境
deploy:review:
stage: deploy
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://$CI_COMMIT_REF_SLUG.example.com
on_stop: stop:review
script:
- deploy-review.sh
only:
- merge_requests
stop:review:
stage: deploy
environment:
name: review/$CI_COMMIT_REF_NAME
action: stop
script:
- cleanup-review.sh
when: manual
# 父子 Pipeline
trigger:child:
stage: deploy
trigger:
include: child-pipeline.yml
strategy: depend
Jenkins 實戰
Declarative Pipeline
// Jenkinsfile
pipeline {
agent any
environment {
DOCKER_IMAGE = "myorg/myapp:${BUILD_NUMBER}"
DOCKER_CREDENTIALS = credentials('docker-hub')
}
options {
buildDiscarder(logRotator(numToKeepStr: '10'))
timeout(time: 30, unit: 'MINUTES')
timestamps()
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
sh 'npm ci'
sh 'npm run build'
}
}
stage('Test') {
parallel {
stage('Unit Tests') {
steps {
sh 'npm run test:unit'
}
post {
always {
junit 'junit.xml'
}
}
}
stage('Integration Tests') {
steps {
sh 'npm run test:integration'
}
}
}
}
stage('Security Scan') {
steps {
sh 'npm audit --audit-level=high'
}
}
stage('Docker Build') {
steps {
script {
docker.build(DOCKER_IMAGE)
}
}
}
stage('Docker Push') {
steps {
script {
docker.withRegistry('https://registry.hub.docker.com', 'docker-hub') {
docker.image(DOCKER_IMAGE).push()
docker.image(DOCKER_IMAGE).push('latest')
}
}
}
}
stage('Deploy to Staging') {
when {
branch 'develop'
}
steps {
sh 'kubectl apply -f k8s/staging/'
}
}
stage('Deploy to Production') {
when {
branch 'main'
}
input {
message "Deploy to production?"
ok "Deploy"
}
steps {
sh 'kubectl apply -f k8s/production/'
}
}
}
post {
success {
slackSend(color: 'good', message: "Build succeeded: ${env.JOB_NAME} #${env.BUILD_NUMBER}")
}
failure {
slackSend(color: 'danger', message: "Build failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}")
}
always {
cleanWs()
}
}
}
Shared Library
// vars/standardPipeline.groovy
def call(Map config) {
pipeline {
agent any
stages {
stage('Build') {
steps {
sh "${config.buildCommand ?: 'npm run build'}"
}
}
stage('Test') {
steps {
sh "${config.testCommand ?: 'npm test'}"
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
sh "${config.deployCommand ?: './deploy.sh'}"
}
}
}
}
}
// 使用方式(Jenkinsfile)
@Library('my-shared-library') _
standardPipeline(
buildCommand: 'gradle build',
testCommand: 'gradle test',
deployCommand: 'kubectl apply -f k8s/'
)
部署策略
部署策略比較
| 策略 | 風險 | 回滾速度 | 資源需求 | 複雜度 |
|---|---|---|---|---|
| Rolling Update | 中 | 中 | 低 | 低 |
| Blue-Green | 低 | 快 | 高(2x) | 中 |
| Canary | 低 | 快 | 中 | 高 |
| A/B Testing | 低 | 快 | 中 | 高 |
| Shadow | 最低 | N/A | 高 | 最高 |
1. Rolling Update(滾動更新)
逐步替換舊版本實例。
# Kubernetes Rolling Update
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多多 1 個 Pod
maxUnavailable: 1 # 最多少 1 個 Pod
時間軸:
T1: [v1] [v1] [v1] [v1] # 初始狀態
T2: [v1] [v1] [v1] [v2] # 新增 1 個 v2
T3: [v1] [v1] [v2] [v2] # 替換 1 個 v1
T4: [v1] [v2] [v2] [v2] # 繼續替換
T5: [v2] [v2] [v2] [v2] # 完成更新
2. Blue-Green Deployment(藍綠部署)
同時維護兩套環境,切換流量。
# 藍綠部署配置
# Blue 環境 (當前生產)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-blue
labels:
version: blue
---
# Green 環境 (新版本)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-green
labels:
version: green
---
# Service 切換
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
version: green # 切換到 green
部署流程:
┌─────────────────────────────────────────┐
│ Load Balancer │
│ │ │
│ ┌────┴────┐ │
│ ▼ ▼ │
│ ┌────┐ ┌─────┐ │
│ │Blue│ │Green│ ← 部署新版本 │
│ │ v1 │ │ v2 │ │
│ │100%│ │ 0% │ │
│ └────┘ └─────┘ │
│ │
│ 切換後: │
│ ┌────┐ ┌─────┐ │
│ │Blue│ │Green│ │
│ │ v1 │ │ v2 │ │
│ │ 0% │ │100% │ ← 流量切換 │
│ └────┘ └─────┘ │
└─────────────────────────────────────────┘
3. Canary Deployment(金絲雀部署)
逐步將流量導向新版本。
# Kubernetes + Istio Canary
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp
http:
- route:
- destination:
host: myapp
subset: v1
weight: 90 # 90% 到 v1
- destination:
host: myapp
subset: v2
weight: 10 # 10% 到 v2(金絲雀)
流量分配演進:
階段 1: v1=95%, v2=5% # 小規模測試
階段 2: v1=80%, v2=20% # 擴大測試
階段 3: v1=50%, v2=50% # 半數流量
階段 4: v1=0%, v2=100% # 完成遷移
4. A/B Testing
基於使用者特徵分流。
# Nginx A/B Testing
upstream backend_v1 {
server v1.example.com;
}
upstream backend_v2 {
server v2.example.com;
}
split_clients "${remote_addr}" $variant {
50% backend_v1;
50% backend_v2;
}
server {
location / {
proxy_pass http://$variant;
}
}
回滾策略
# Kubernetes 回滾
# 查看歷史版本
kubectl rollout history deployment/myapp
# 回滾到上一版本
kubectl rollout undo deployment/myapp
# 回滾到特定版本
kubectl rollout undo deployment/myapp --to-revision=2
# 暫停/恢復部署
kubectl rollout pause deployment/myapp
kubectl rollout resume deployment/myapp
最佳實踐
1. Pipeline 設計原則
# ✅ 快速反饋
fast-feedback:
stages:
- lint # 秒級
- unit-test # 秒-分鐘級
- build # 分鐘級
- integration # 分鐘級
- e2e # 分鐘-小時級
# ✅ 平行執行
parallel-jobs:
test:
parallel:
- unit
- lint
- security-scan
# ✅ 快取依賴
cache:
paths:
- node_modules/
- ~/.m2/
- ~/.gradle/
2. 安全實踐
# ✅ 密鑰管理
secrets:
# 使用環境變數,不硬編碼
- name: Deploy
env:
API_KEY: ${{ secrets.API_KEY }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
# ✅ 最小權限
permissions:
contents: read
packages: write
# ✅ 依賴鎖定
install:
# 使用 lock file
- npm ci # 不是 npm install
- pip install -r requirements.txt --require-hashes
3. 建構最佳實踐
# ✅ 多階段建構減少映像大小
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-slim AS production
WORKDIR /app
COPY /app/dist ./dist
COPY /app/node_modules ./node_modules
USER node
CMD ["node", "dist/main.js"]
4. 測試策略
# ✅ 測試金字塔
test-strategy:
unit:
coverage: 80% # 高覆蓋率
timeout: 5m
integration:
coverage: 60%
timeout: 15m
services:
- database
e2e:
coverage: critical-paths # 關鍵路徑
timeout: 30m
5. 監控與通知
# ✅ 部署後驗證
post-deploy:
- health-check:
endpoint: /health
timeout: 5m
- smoke-test:
script: ./smoke-tests.sh
- notify:
channels:
- slack: #deployments
- email: team@example.com
6. 文件化
# ✅ Pipeline 文件
# pipeline.yml
#
# 此 Pipeline 執行以下任務:
# 1. 建構 - 編譯程式碼並建構 Docker 映像
# 2. 測試 - 執行單元測試和整合測試
# 3. 部署 - 部署到 staging/production
#
# 觸發條件:
# - push to main: 部署到 production
# - push to develop: 部署到 staging
# - PR: 僅執行建構和測試
#
# 必要密鑰:
# - DOCKER_TOKEN: Docker Hub 存取權杖
# - KUBE_CONFIG: Kubernetes 配置
常見問題
Pipeline 執行太慢?
解決方案:
# 1. 平行執行
test:
parallel:
matrix:
- shard: [1, 2, 3, 4]
script: npm test -- --shard=$shard/4
# 2. 快取依賴
cache:
key: deps-${{ hashFiles('package-lock.json') }}
paths:
- node_modules/
# 3. 增量建構
build:
script:
- npm run build -- --incremental
# 4. 選擇性執行
test:
rules:
- changes:
- src/**/*
- tests/**/*
如何處理 Flaky Tests?
# 1. 重試機制
test:
retry:
max: 2
when:
- runner_system_failure
- stuck_or_timeout_failure
# 2. 隔離測試
test:
parallel: 4 # 分散執行
# 3. 標記並追蹤
test:
script: |
npm test --reporter=junit
# 將 flaky tests 報告到追蹤系統
如何管理多環境配置?
# 使用環境變數
.deploy:
script:
- envsubst < k8s/deployment.tmpl > k8s/deployment.yaml
- kubectl apply -f k8s/deployment.yaml
deploy:staging:
extends: .deploy
variables:
ENVIRONMENT: staging
REPLICAS: 2
deploy:production:
extends: .deploy
variables:
ENVIRONMENT: production
REPLICAS: 5
如何實現零停機部署?
# 1. 健康檢查
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
# 2. 優雅關閉
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10"]
# 3. 滾動更新策略
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 0 # 不允許服務中斷
總結
CI/CD 核心流程
┌──────────┐ ┌───────┐ ┌──────┐ ┌──────────┐ ┌─────────┐
│ Source │ → │ Build │ → │ Test │ → │ Security │ → │ Deploy │
└──────────┘ └───────┘ └──────┘ └──────────┘ └─────────┘
Code Compile Unit SAST Staging
Commit Package Integration SCA Production
PR Docker E2E Container Monitor
工具選擇快速指南
| 需求 | 推薦工具 |
|---|---|
| GitHub 專案 | GitHub Actions |
| GitLab 專案 | GitLab CI/CD |
| 企業內部、高度自訂 | Jenkins |
| Kubernetes 環境 | Argo CD / Tekton |
| 簡單快速上手 | CircleCI |
部署策略選擇
| 需求 | 推薦策略 |
|---|---|
| 簡單、低風險 | Rolling Update |
| 快速回滾需求 | Blue-Green |
| 漸進式驗證 | Canary |
| 功能實驗 | A/B Testing |
Pipeline 設計檢查清單
- 建構階段:Lint、Compile、Package、Docker Build
- 測試階段:Unit、Integration、E2E
- 安全掃描:SAST、SCA、Container Scan
- 部署階段:Staging → Production
- 監控驗證:Health Check、Smoke Test
- 通知機制:Success/Failure 通知
- 快取策略:依賴快取、建構快取
- 密鑰管理:使用 Secrets,不硬編碼
建立日期:2025-12-05 最後更新:2025-12-05