2. 动态交付概念:蓝绿部署、金丝雀发布、滚动更新

2.1 动态交付到底在解决什么问题?

你想想看,一个应用上线,最怕什么?

我最怕新版本推上去,用户直接报错,然后一群人围过来问「怎么回事」。传统的停机更新,说白了就是拿业务连续性赌一把。赌赢了没人夸你,赌输了背锅的就是你。

动态交付要解决的,本质上就两件事:降低风险 和 提升效率。让新版本先在小范围验证,确认没问题再全量推,出问题能秒级回滚。这不是什么花架子,是生产环境活下去的必备能力。

下面三种策略,是业界公认的三种主流玩法。我在不同项目里都用过,各有各的脾气,咱们一个一个说。

核心共识: 没有银弹。蓝绿、金丝雀、滚动,选哪个取决于你的业务容忍度、基础设施能力和团队运维水平。
动态交付策略全景 动态交付策略 蓝绿部署 金丝雀发布 滚动更新 两套环境 瞬时切换 灰度放量 监控验证 分批替换 零停机 可靠交付

2.2 蓝绿部署:简单粗暴,但好用

蓝绿部署的思路,说白了就是准备两套一模一样的环境——一套叫蓝,一套叫绿。任何时候只有一套在对外服务,另一套闲着。

你要发新版,就把新版部署到空闲的那套上,然后做个全量切换。比如之前是蓝环境在线,你把绿环境部署好新版本,测一下没问题,把流量切到绿环境。如果出事了,再切回蓝环境,回滚就是秒级的事。

我在一个金融项目里用过这个模式。当时是核心交易系统,停机一秒都是大事。我们搭了两套完全独立的环境,数据库也做了双写。切换的时候,我盯着监控屏,心跳都加快了。好在一切顺利,从切流量到确认稳定,前后不到30秒。

我的习惯: 蓝绿部署最容易被忽略的是「数据兼容性」。两套环境共享数据库?还是各自独立?如果你只是切应用层,数据库只有一个,那回滚时数据可能已经写乱了。这点一定要在设计阶段就想清楚。

蓝绿部署的优缺点很明显:

  • 优点: 切换极快、回滚极快、流程简单、运维压力小。
  • 缺点: 资源成本翻倍,等于你得养着一套几乎不产生价值的空闲环境。
  • 适用场景: 核心业务、对停机零容忍的系统、团队规模不大的中小项目。

下面是一个简化版的蓝绿切换 Service 配置示意:

# 蓝色环境 Service(当前在线)
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  selector:
    app: my-app
    version: blue      # 指向蓝色环境
  ports:
    - port: 80
      targetPort: 8080

# 需要切换时,只需将 version 改为 green
# 然后 apply 即可,kube-proxy 会立即更新转发规则

2.3 金丝雀发布:先派一只鸟探路

金丝雀发布的名字来自煤矿里的金丝雀——先放一只鸟进去,如果鸟没事,人才进去。这个比喻很形象,说白了就是先让一小部分用户用新版本,观察一会儿没问题,再逐步放大流量比例。

我曾在一次电商大促前做金丝雀发布。当时只放了5%的流量到新版本,结果监控发现新版本的内存泄漏——虽然不致命,但跑24小时肯定出事。幸好只放了5%,回滚影响面极小。要是直接全量推,那天晚上就别想睡了。

金丝雀发布的核心在于:用真实流量做验证。测试环境永远无法模拟生产环境的所有情况,尤其是并发量、数据分布、第三方依赖的异常行为。

我曾经踩过的坑: 金丝雀发布时,别忘了关注「数据面」的隔离。比如新版本写了不同的日志格式,或者改了缓存key的命名规则,老版本可能读不到。灰度不光是流量灰度,数据兼容性也得灰度验证。

金丝雀发布的典型流程:

  1. 部署新版本,只分配 1%-5% 的流量。
  2. 持续监控错误率、延迟、业务指标(如订单量、支付成功率)。
  3. 观察期从几分钟到几小时不等,视业务重要程度而定。
  4. 确认稳定后,逐步扩大到 10%、30%、50%、100%。
  5. 如果任何一步出现异常,立即将流量切回旧版本。

它的优缺点也很清晰:

  • 优点: 风险极低、真实流量验证、适合大规模系统。
  • 缺点: 发布周期较长、对监控体系要求高、需要精细的流量控制能力。
  • 适用场景: 用户量大的互联网服务、微服务架构、对稳定性极其敏感的系统。

2.4 滚动更新:温吞水,但实在

滚动更新是Kubernetes默认的更新策略。它的做法是:一次替换一部分旧实例,逐步全部换成新版本。整个过程没有独立的环境,就是在现有集群里"温水煮青蛙"式地替换。

我记得有一年在做容器化迁移,整个集群有200多个节点。我用滚动更新推送新版本,一次替换20%的实例。过程平稳得让我有点不习惯——没有告警,没有报错,业务完全无感知。

滚动更新的关键参数: maxSurge(允许超出期望副本数的最大实例数)和 maxUnavailable(允许不可用的最大实例数)。这两个参数决定了更新的速度和安全性。

但滚动更新也有它的软肋。最麻烦的是版本兼容性——滚动过程中,新旧版本会同时在线提供服务。如果你的新版本改了API接口或者数据库结构,老版本还在处理请求,很容易出问题。

下面是一个典型的 Kubernetes 滚动更新配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2          # 允许最多超出 2 个实例
      maxUnavailable: 1    # 允许最多 1 个实例不可用
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: my-app:2.0.0
          readinessProbe:   # 就绪探针,确保新实例真正就绪
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 5

滚动更新的优缺点:

  • 优点: 无需额外资源、零停机、自动化程度高、适合大规模集群。
  • 缺点: 回滚复杂(需要再滚动一次)、新旧版本兼容性要求高、更新速度相对较慢。
  • 适用场景: 资源有限的环境、无状态服务、微服务架构中的大部分非核心服务。

2.5 三种策略对比

策略 切换速度 资源成本 风险等级 回滚难度 流量控制粒度
蓝绿部署 秒级 高(2倍资源) 低 低 全量
金丝雀发布 分钟级~小时级 中(N+少量) 低 中 百分比
滚动更新 分钟级 低(N) 中 高 实例级

2.6 怎么选?我的几条原则

说实话,没有标准答案。但我可以分享几条我自己的判断依据:

  • 业务容忍度: 如果出问题10秒就有人投诉,选蓝绿或金丝雀。如果业务天然能容忍短时波动,滚动更新完全够用。
  • 基础设施预算: 有钱上蓝绿,没钱上滚动。金丝雀居中,但需要流量控制组件(比如Service Mesh或Ingress Controller)。
  • 团队运维能力: 蓝绿最「笨」但最稳,滚动最「聪明」但对兼容性要求高。团队如果还在爬坡期,别搞太复杂的灰度策略。
  • 系统架构: 有状态服务(比如数据库)别轻易搞滚动,蓝绿配合双写更安全。无状态服务可以放心用滚动。
一个小建议: 别试图在项目初期就制定「完美」的交付策略。先用蓝绿或滚动把流程跑起来,后面再根据实际情况迭代。先做到「可交付」,再追求「优雅交付」。

三种策略不是互斥的。我在一些大型项目里,核心服务用蓝绿,普通服务用滚动,新功能灰度用金丝雀。它们可以共存,关键是你得清楚每种策略的适用边界。