第十九篇:《滚动更新与回滚、蓝绿部署、金丝雀发布》

发布新版本时,最怕的就是"上线即故障"。Kubernetes 提供了多种部署策略来降低发布风险:滚动更新是默认的零停机方案,蓝绿部署实现快速切换和秒级回滚,金丝雀发布则通过渐进式流量验证新版本。本文将系统讲解这三种策略的原理、配置方法和适用场景,并介绍 Argo Rollouts 等自动化工具。

一、滚动更新(Rolling Update):零停机的默认策略

滚动更新是 Kubernetes Deployment 的默认更新策略。它通过逐步用新版本 Pod 替换旧版本 Pod的方式,实现零停机更新。

1.1 工作原理

当执行 kubectl set image 或修改 Deployment 的镜像版本时,Kubernetes 会:

创建一个新的 ReplicaSet(新版本)。

逐步扩容新 ReplicaSet,同时缩容旧 ReplicaSet。

每次替换一部分 Pod,直到全部替换完成。

默认情况下,更新期间最多 1 个 Pod 不可用,同时最多 额外创建 1 个新 Pod。

1.2 核心参数:maxSurge 与 maxUnavailable

通过 strategy.rollingUpdate 可以精细控制更新过程:

参数 含义 默认值

maxSurge 更新期间可以超出期望副本数的最大 Pod 数量(绝对数或百分比) 25%

maxUnavailable 更新期间允许不可用的最大 Pod 数量(绝对数或百分比) 25%

配置示例:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # 最多额外创建 1 个 Pod
      maxUnavailable: 0  # 不允许任何 Pod 不可用
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25

当 replicas=3、maxSurge=1、maxUnavailable=0 时,更新期间始终至少有 3 个可用实例,最多同时存在 4 个 Pod(3 旧 + 1 新)。

1.3 执行滚动更新

bash 复制代码
# 方式1:直接更新镜像
kubectl set image deployment/nginx nginx=nginx:1.26

# 方式2:编辑 Deployment 配置
kubectl edit deployment nginx

# 方式3:应用新的 YAML 文件
kubectl apply -f deployment-v2.yaml

1.4 查看更新状态与回滚

bash 复制代码
# 查看更新状态
kubectl rollout status deployment/nginx

# 查看历史版本
kubectl rollout history deployment/nginx

# 回滚到上一版本
kubectl rollout undo deployment/nginx

# 回滚到指定版本
kubectl rollout undo deployment/nginx --to-revision=2

关键参数补充:

minReadySeconds:新 Pod 就绪后等待指定秒数才被视为可用。

revisionHistoryLimit:保留的历史 ReplicaSet 数量,默认 10 个。

progressDeadlineSeconds:更新超时时间,超时则标记为失败。

二、蓝绿部署(Blue-Green Deployment):快速切换与秒级回滚

蓝绿部署维护两套完全独立的环境:蓝色(当前生产版本)和绿色(新版本)。验证通过后,通过切换 Service 的标签选择器将流量一次性切换到新版本。

2.1 实现方式

步骤:

蓝色环境(v1)正常运行,Service 指向蓝色 Deployment。

部署绿色环境(v2),独立 Deployment 和 Service(或复用同一 Service)。

验证绿色环境功能正常。

切换 Service 的 selector 指向绿色 Deployment。

如需回滚,只需将 selector 切回蓝色。

YAML 示例:

yaml

yaml 复制代码
# 蓝色 Deployment (v1)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-blue
  labels:
    app: myapp
    version: blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      version: blue
  template:
    metadata:
      labels:
        app: myapp
        version: blue
    spec:
      containers:
      - name: app
        image: myapp:v1
---
# 绿色 Deployment (v2)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-green
  labels:
    app: myapp
    version: green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      version: green
  template:
    metadata:
      labels:
        app: myapp
        version: green
    spec:
      containers:
      - name: app
        image: myapp:v2
---
# Service(通过修改 selector 切换流量)
apiVersion: v1
kind: Service
metadata:
  name: app-svc
spec:
  selector:
    app: myapp
    version: blue   # 切换为 green 即完成发布
  ports:
  - port: 80
    targetPort: 8080
2.2 优缺点
优点	缺点
切换速度快(秒级)	需要双倍资源(两套环境同时运行)
回滚只需切换 selector	数据库变更需兼容新旧版本
新版本独立验证,不影响生产	不适合频繁发布(资源浪费)
2.3 自动化工具
Flagger:自动化蓝绿部署,支持指标分析和自动回滚。

Argo Rollouts:通过 Rollout CRD 实现蓝绿和金丝雀部署。

三、金丝雀发布(Canary Release):渐进式验证
金丝雀发布将新版本逐步暴露给一小部分流量,验证稳定后再逐步扩大范围。若发现问题,影响范围极小,可立即回滚。

3.1 基于 Ingress 流量权重的实现(最常用)
Nginx Ingress Controller 通过专用注解实现金丝雀发布。

步骤:

部署稳定版(v1)Service 和 Ingress。

部署金丝雀版(v2)Deployment 和 Service。

创建金丝雀 Ingress,配置流量权重。

YAML 示例:

yaml
# 稳定版 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-v1-svc
            port:
              number: 80
---
# 金丝雀版 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"   # 10% 流量到新版本
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-v2-svc
            port:
              number: 80

金丝雀 Ingress 的 canary-weight 控制流向新版本的流量比例。验证稳定后,逐步调高权重(10% → 50% → 100%),最终将流量全部切到新版本。

3.2 基于请求头的金丝雀发布

除了按权重分流,Nginx Ingress 还支持基于请求头(Header)的流量切分:

yaml 复制代码
annotations:
  nginx.ingress.kubernetes.io/canary: "true"
  nginx.ingress.kubernetes.io/canary-by-header: "Canary"
  nginx.ingress.kubernetes.io/canary-by-header-value: "true"

只有携带 Canary: true 头部的请求才会路由到新版本,适合内部测试或 A/B 测试。

3.3 自动化金丝雀发布:Argo Rollouts

Argo Rollouts 是 Kubernetes 渐进式交付的标准工具,通过 Rollout CRD 扩展原生 Deployment。

Rollout 配置示例:

yaml 复制代码
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: app-rollout
spec:
  replicas: 10
  strategy:
    canary:
      steps:
      - setWeight: 10      # 第一步:10% 流量
      - pause: {duration: 5m}  # 暂停 5 分钟观察
      - setWeight: 50      # 第二步:50% 流量
      - pause: {duration: 5m}
      - setWeight: 100     # 第三步:100% 流量
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: app
        image: myapp:v2

Argo Rollouts 支持自动回滚:当错误率超过阈值时自动回滚。可集成 Prometheus 等监控系统,实现基于指标分析的智能发布。

四、三种策略对比与选型

选型建议:

日常迭代:滚动更新即可满足大多数场景。

大版本升级:蓝绿部署,快速切换和回滚。

核心业务:金丝雀发布,真实流量验证,把风险降到最低。

自动化需求:Argo Rollouts + Flagger 实现渐进式交付。

五、小结

滚动更新、蓝绿部署和金丝雀发布各有侧重:滚动更新是零停机的默认选择;蓝绿部署以双倍资源换取秒级切换和回滚;金丝雀发布通过渐进式流量验证实现最低风险发布。根据业务场景选择合适的策略,并结合 Argo Rollouts 等工具实现自动化,可以显著提升发布的安全性和效率。