跳到主要内容

流水线设计与部署策略

流水线设计原则

标准流水线阶段

设计原则

原则说明
快速反馈Lint 和单元测试放在最前面,5 分钟内给出结果
并行执行无依赖的 Job 并行运行(lint ∥ test ∥ security scan)
缓存复用依赖缓存(node_modules、.m2)、Docker 层缓存
制品不可变构建一次镜像,在 staging → production 之间只改配置
环境一致所有环境使用相同的 Docker 镜像和 Helm Chart
门禁机制PR 必须通过 CI 才能合并,生产部署需要审批

PR 门禁示例

GitHub Actions PR 门禁
on:
pull_request:
branches: [main]

jobs:
gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pnpm install --frozen-lockfile
- run: pnpm lint # 代码规范
- run: pnpm type-check # 类型检查
- run: pnpm test -- --coverage # 测试覆盖率
- run: pnpm build # 构建验证

# 覆盖率门禁
- uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true

部署策略详解

滚动更新(Rolling Update)

K8s 默认策略,逐步替换旧 Pod。

Deployment 滚动更新
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多多 1 个 Pod
maxUnavailable: 1 # 最多少 1 个 Pod

优点:资源开销小,K8s 原生支持。 缺点:新旧版本共存期间可能有兼容性问题。

蓝绿部署(Blue-Green)

同时运行两套完整环境,通过 Service 切换流量。

蓝绿部署 - Service 切流量
# Blue(当前线上)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: blue
---
# Green(新版本)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: green
---
# Service 指向 Blue → 切换到 Green
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
spec:
selector:
app: myapp
version: blue # 切换时改为 green
# 切换流量:将 Service 指向 Green
kubectl patch svc myapp-svc -p '{"spec":{"selector":{"version":"green"}}}'

# 回滚:切回 Blue
kubectl patch svc myapp-svc -p '{"spec":{"selector":{"version":"blue"}}}'

优点:回滚极快(切换 Service),无新旧版本共存。 缺点:需要双倍资源。

金丝雀发布(Canary)

先将少量流量导到新版本,观察无异常后逐步扩大。

基于 Nginx Ingress 的金丝雀
# 主 Ingress(v1,100% 流量)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-main
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-v1
port:
number: 80
---
# Canary Ingress(v2,5% 流量)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "5" # 5% 流量
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-v2
port:
number: 80
渐进式交付工具

手动管理金丝雀很繁琐,推荐使用自动化工具:

  • Argo Rollouts:K8s 原生的渐进式交付控制器
  • Flagger:配合 Istio/Nginx 自动金丝雀发布
  • Istio:通过 VirtualService 精确控制流量分配

策略选型

场景推荐策略
日常发布,容忍短暂新旧共存滚动更新
数据库迁移等需要原子切换蓝绿部署
核心服务,需要灰度验证金丝雀发布
需要按用户分流对比A/B 测试(需要 Istio)

多环境管理

环境用途部署方式数据
Dev开发自测自动(push 触发)Mock 数据
Staging预发布验证自动(main 分支)脱敏数据
Production用户访问手动审批真实数据
ReviewMR 预览自动(MR 触发)Mock 数据

常见面试问题

Q1: 蓝绿部署和金丝雀发布的区别?

答案

维度蓝绿部署金丝雀发布
流量切换一次性 100% 切换逐步从 5% → 100%
新旧共存不共存(原子切换)共存(观察期)
资源需要双倍资源只需少量额外资源
回滚极快(切回旧版本)快(关闭金丝雀)
风险切换时全量影响风险可控(只影响小流量)
适用需要原子发布需要灰度验证

Q2: 如何设计一条生产级 CI/CD 流水线?

答案

  1. PR 阶段:Lint → 单元测试 → 构建验证 → 安全扫描(SAST)
  2. 合并 main:构建 Docker 镜像 → 推送 Registry → 自动部署 Staging
  3. Staging:集成测试 → 冒烟测试 → 性能测试
  4. Production:手动审批 → 金丝雀发布(5% → 25% → 100%) → 自动回滚(错误率增高时)

关键原则:制品不可变、快速反馈、门禁机制、自动回滚。

Q3: CI 流水线太慢怎么优化?

答案

  1. 缓存:依赖缓存(node_modules / .m2)、Docker 层缓存
  2. 并行:lint / test / security-scan 并行执行
  3. 增量:路径过滤(只测试变更的模块)、增量构建
  4. 资源:self-hosted runner 提升性能,K8s Agent 弹性伸缩
  5. 精简镜像:多阶段构建减小镜像体积,加速推送

相关链接