CI/CD 流水线从设计到落地
设计目标
在搭建 CI/CD 流水线之前,先明确目标:
- 每次 PR 自动运行测试和代码检查
- 合并到 main 后自动构建镜像并部署到 staging
- 手动触发生产部署
- 回滚能力
流水线设计
CI 阶段(PR 触发)
name: CI
on:
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 运行测试
run: |
pip install -r requirements.txt
pytest --cov=./ --cov-report=xml
- name: 代码检查
run: ruff check .
CD 阶段(合并到 main 触发)
name: CD
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 构建 Docker 镜像
run: |
docker build -t myapp:${{ github.sha }} .
docker push registry.example.com/myapp:${{ github.sha }}
- name: 部署到 staging
run: |
kubectl set image deployment/myapp \
myapp=registry.example.com/myapp:${{ github.sha }}
关键决策
1. 单仓库 vs 多仓库
对于中小团队,单仓库 + 路径过滤 比多仓库更省心。不需要管理多个仓库的权限、Webhook、Secret。
2. 镜像标签策略
不要用 latest 标签。用 git commit SHA 作为镜像标签,保证可追溯。每次部署记录 commit SHA 和部署时间。
3. 环境分离
staging 和 production 应该使用不同的 Kubernetes 命名空间和不同的 Service Account。staging 可以用假的 Secret,production 用真的。
经验教训
-
测试要快:CI 流水线超过 10 分钟,开发者就开始跳过推代码直接合并了。把单元测试和集成测试分开,CI 只跑单元测试。
-
环境一致性:最痛苦的事情是 “在我电脑上是好的”。用 Docker 确保开发、测试、生产环境一致。
-
回滚要简单:
kubectl rollout undo是最简单的回滚方式。确保每次部署前都记录上一个版本的镜像 SHA。
下一步
接下来计划引入金丝雀发布和自动回滚——当新版本的错误率超过阈值时自动回滚。