主题
高级发布策略
业务场景
云咖啡公司的用户量持续增长,每次应用更新都需要保证服务不中断。运维团队要求:
- 发布过程中用户无感知
- 出现问题能够快速回滚
- 新版本可以先让部分用户验证
作为运维工程师,你需要掌握多种发布策略,确保云咖啡系统的平稳升级。
学习目标
完成本阶段后,你将掌握:
- 滚动更新:K8S 默认的发布策略
- 蓝绿发布:快速切换,即时回滚
- 金丝雀发布:渐进式发布,降低风险
- 发布策略选择:根据场景选择合适的发布方式
前置知识
本阶段需要以下基础知识:
- 完成 K8S 实战课程前九个阶段
- 熟悉 Deployment 的基本操作
- 了解 Service 的工作原理
第一部分:发布策略概述
为什么需要发布策略
在生产环境中,应用更新面临以下挑战:
| 挑战 | 影响 |
|---|---|
| 服务中断 | 用户无法访问,影响业务 |
| 新版本缺陷 | 影响所有用户 |
| 回滚困难 | 恢复时间长 |
| 资源限制 | 无法同时运行多个版本 |
发布策略对比
| 策略 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 滚动更新 | 逐步替换 Pod | 资源占用少 | 新旧版本共存 | 常规更新 |
| 蓝绿发布 | 两套环境切换 | 切换快、回滚快 | 资源占用双倍 | 关键业务 |
| 金丝雀发布 | 逐步增加流量 | 风险可控 | 发布时间长 | 大规模系统 |
第二部分:滚动更新
什么是滚动更新
滚动更新是 K8S Deployment 的默认发布策略。它逐步创建新版本的 Pod,同时删除旧版本的 Pod,确保始终有足够数量的 Pod 在运行。
工作原理
初始状态: [v1] [v1] [v1] [v1] [v1] (5个副本)
步骤1: [v2] [v1] [v1] [v1] [v1] (创建1个v2,删除1个v1)
步骤2: [v2] [v2] [v1] [v1] [v1] (继续替换)
步骤3: [v2] [v2] [v2] [v1] [v1]
步骤4: [v2] [v2] [v2] [v2] [v1]
步骤5: [v2] [v2] [v2] [v2] [v2] (完成)配置示例
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee-shop
namespace: cloud-coffee
spec:
replicas: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多可以超出期望副本数的数量(或百分比)
maxUnavailable: 1 # 最多可以不可用的副本数(或百分比)
selector:
matchLabels:
app: coffee-shop
template:
metadata:
labels:
app: coffee-shop
spec:
containers:
- name: coffee-shop
image: nginx:1.24
ports:
- containerPort: 80参数说明:
| 参数 | 默认值 | 说明 |
|---|---|---|
maxSurge | 25% | 更新期间最多可以创建的额外 Pod 数量 |
maxUnavailable | 25% | 更新期间最多可以不可用的 Pod 数量 |
执行滚动更新
bash
# 更新镜像版本
kubectl set image deployment/coffee-shop coffee-shop=nginx:1.25 -n cloud-coffee
# 查看更新状态
kubectl rollout status deployment/coffee-shop -n cloud-coffee
# 查看更新历史
kubectl rollout history deployment/coffee-shop -n cloud-coffee
# 回滚到上一个版本
kubectl rollout undo deployment/coffee-shop -n cloud-coffee
# 回滚到指定版本
kubectl rollout undo deployment/coffee-shop --to-revision=2 -n cloud-coffee📌 关于
kubectl rollout命令的解释
kubectl rollout用于管理 Deployment、DaemonSet、StatefulSet 的滚动更新。常用子命令:
命令 作用 rollout status查看滚动更新状态 rollout history查看更新历史版本 rollout undo回滚到之前版本 rollout pause暂停更新(用于金丝雀发布) rollout resume恢复暂停的更新 rollout restart重启 Pod(触发重新部署) **
--to-revision参数**:
- 指定回滚到特定版本号
- 版本号从
rollout history中获取- 不指定则回滚到上一个版本
示例:
bash# 查看历史版本 kubectl rollout history deployment/myapp # 回滚到指定版本 kubectl rollout undo deployment/myapp --to-revision=3 # 重启 Deployment(重新创建 Pod) kubectl rollout restart deployment/myapp
暂停和恢复更新
bash
# 暂停更新(用于金丝雀发布)
kubectl rollout pause deployment/coffee-shop -n cloud-coffee
# 恢复更新
kubectl rollout resume deployment/coffee-shop -n cloud-coffee第三部分:蓝绿发布
什么是蓝绿发布
蓝绿发布维护两套完全相同的生产环境(蓝色和绿色),通过切换流量实现发布。蓝色环境运行当前版本,绿色环境运行新版本。
工作原理
发布前:
蓝色环境: [v1] [v1] [v1] ← Service 指向这里(100% 流量)
绿色环境: [v2] [v2] [v2] ← 新版本,待验证
切换后:
蓝色环境: [v1] [v1] [v1] ← 保留,用于回滚
绿色环境: [v2] [v2] [v2] ← Service 指向这里(100% 流量)实现方式
方式一:通过 Service selector 切换
yaml
# 蓝色环境 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee-shop-blue
namespace: cloud-coffee
spec:
replicas: 3
selector:
matchLabels:
app: coffee-shop
version: blue
template:
metadata:
labels:
app: coffee-shop
version: blue
spec:
containers:
- name: coffee-shop
image: nginx:1.24
---
# 绿色环境 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee-shop-green
namespace: cloud-coffee
spec:
replicas: 3
selector:
matchLabels:
app: coffee-shop
version: green
template:
metadata:
labels:
app: coffee-shop
version: green
spec:
containers:
- name: coffee-shop
image: nginx:1.25
---
# Service(初始指向蓝色环境)
apiVersion: v1
kind: Service
metadata:
name: coffee-shop
namespace: cloud-coffee
spec:
selector:
app: coffee-shop
version: blue # 切换为 green 即可完成发布
ports:
- port: 80
targetPort: 80切换流量:
bash
# 切换到绿色环境
kubectl patch service coffee-shop -n cloud-coffee -p '{"spec":{"selector":{"version":"green"}}}'
# 回滚到蓝色环境
kubectl patch service coffee-shop -n cloud-coffee -p '{"spec":{"selector":{"version":"blue"}}}'📌 关于
kubectl patch和-p参数的解释
kubectl patch用于部分更新资源,只修改指定的字段而不影响其他配置。**
-p/--patch参数**:指定要应用的 patch 内容
- 支持 JSON 格式(如本例)
- 支持 YAML 格式(使用
-p $(cat patch.yaml))- 支持 Strategic Merge Patch
Patch 类型对比:
类型 命令 适用场景 JSON Patch kubectl patch ... -p '{"spec":{...}}'精确修改特定字段 Merge Patch kubectl patch ... --type=merge ...合并配置 Strategic Merge 默认类型 智能合并数组和对象 使用场景:
bash# 修改 Deployment 副本数 kubectl patch deployment myapp -p '{"spec":{"replicas":5}}' # 修改 Service 类型 kubectl patch svc myapp -p '{"spec":{"type":"NodePort"}}' # 添加标签 kubectl patch pod mypod -p '{"metadata":{"labels":{"env":"prod"}}}'提示:对于复杂修改,建议使用
kubectl edit或kubectl apply -f
方式二:通过 Ingress 切换
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: coffee-shop
namespace: cloud-coffee
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "100" # 切换权重
spec:
rules:
- host: coffee.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: coffee-shop-green # 切换服务
port:
number: 80蓝绿发布流程
1. 部署绿色环境(新版本)
↓
2. 验证绿色环境(健康检查、功能测试)
↓
3. 切换流量到绿色环境
↓
4. 监控新版本运行状态
↓
5a. 正常:保留蓝色环境作为备份
5b. 异常:快速切换回蓝色环境第四部分:金丝雀发布
什么是金丝雀发布
金丝雀发布(Canary Release)源自矿工用金丝雀检测有毒气体的做法。在软件发布中,先让一小部分用户使用新版本,验证无问题后再逐步扩大范围。
工作原理
步骤1: [v1] [v1] [v1] [v1] [v2] ← v2 承担 20% 流量
↓ 验证通过
步骤2: [v1] [v1] [v1] [v2] [v2] ← v2 承担 40% 流量
↓ 验证通过
步骤3: [v1] [v1] [v2] [v2] [v2] ← v2 承担 60% 流量
↓ 验证通过
最终: [v2] [v2] [v2] [v2] [v2] ← v2 承担 100% 流量实现方式
方式一:通过调整副本数
bash
# 初始状态:10个 v1 副本
kubectl scale deployment coffee-shop-stable --replicas=10 -n cloud-coffee
# 步骤1:10% 流量到新版本
kubectl scale deployment coffee-shop-stable --replicas=9 -n cloud-coffee
kubectl scale deployment coffee-shop-canary --replicas=1 -n cloud-coffee
# 步骤2:30% 流量到新版本
kubectl scale deployment coffee-shop-stable --replicas=7 -n cloud-coffee
kubectl scale deployment coffee-shop-canary --replicas=3 -n cloud-coffee
# 步骤3:50% 流量到新版本
kubectl scale deployment coffee-shop-stable --replicas=5 -n cloud-coffee
kubectl scale deployment coffee-shop-canary --replicas=5 -n cloud-coffee
# 完成:100% 流量到新版本
kubectl scale deployment coffee-shop-stable --replicas=0 -n cloud-coffee
kubectl scale deployment coffee-shop-canary --replicas=10 -n cloud-coffee方式二:使用 Nginx Ingress Canary
yaml
# 稳定版本 Service
apiVersion: v1
kind: Service
metadata:
name: coffee-shop-stable
namespace: cloud-coffee
spec:
selector:
app: coffee-shop
version: stable
ports:
- port: 80
---
# 金丝雀版本 Service
apiVersion: v1
kind: Service
metadata:
name: coffee-shop-canary
namespace: cloud-coffee
spec:
selector:
app: coffee-shop
version: canary
ports:
- port: 80
---
# 稳定版本 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: coffee-shop-stable
namespace: cloud-coffee
spec:
rules:
- host: coffee.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: coffee-shop-stable
port:
number: 80
---
# 金丝雀版本 Ingress(基于权重)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: coffee-shop-canary
namespace: cloud-coffee
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10" # 10% 流量
spec:
rules:
- host: coffee.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: coffee-shop-canary
port:
number: 80调整流量比例:
bash
# 调整金丝雀权重
kubectl annotate ingress coffee-shop-canary -n cloud-coffee \
nginx.ingress.kubernetes.io/canary-weight=30 --overwrite
# 逐步增加
kubectl annotate ingress coffee-shop-canary -n cloud-coffee \
nginx.ingress.kubernetes.io/canary-weight=50 --overwrite
# 完成发布
kubectl annotate ingress coffee-shop-canary -n cloud-coffee \
nginx.ingress.kubernetes.io/canary-weight=100 --overwrite方式三:基于请求特征的流量分流
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: coffee-shop-canary
namespace: cloud-coffee
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-by-header: "X-Canary" # 基于请求头
# 或
# nginx.ingress.kubernetes.io/canary-by-cookie: "canary" # 基于 Cookie
spec:
rules:
- host: coffee.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: coffee-shop-canary
port:
number: 80测试:
bash
# 带 canary 请求头的请求会路由到新版本
curl -H "X-Canary: always" http://coffee.example.com
# 不带请求头的请求会路由到稳定版本
curl http://coffee.example.com第五部分:发布策略选择
决策流程
开始发布
↓
是否需要零停机?
├── 否 → 直接替换(不推荐)
└── 是 ↓
是否有足够资源?
├── 否 → 滚动更新
└── 是 ↓
是否需要快速回滚?
├── 否 → 金丝雀发布
└── 是 ↓
业务是否关键?
├── 是 → 蓝绿发布
└── 否 → 滚动更新场景推荐
| 场景 | 推荐策略 | 原因 |
|---|---|---|
| 常规功能更新 | 滚动更新 | 资源占用少,操作简单 |
| 核心系统升级 | 蓝绿发布 | 快速回滚,风险可控 |
| 大规模用户系统 | 金丝雀发布 | 渐进验证,降低影响范围 |
| 修复紧急 Bug | 滚动更新 | 快速上线 |
| 大版本重构 | 蓝绿 + 金丝雀 | 先金丝雀验证,再蓝绿切换 |
最佳实践
发布前检查
- 确保健康检查配置正确
- 验证新版本在测试环境通过
- 准备回滚方案
发布中监控
- 监控错误率、响应时间
- 关注业务指标
- 设置告警阈值
发布后验证
- 验证核心功能正常
- 检查日志无异常
- 确认用户反馈正常
实战任务
完成以下任务巩固所学知识:
滚动更新实践
- 部署一个 5 副本的应用
- 执行滚动更新,观察 Pod 替换过程
- 练习回滚操作
蓝绿发布实践
- 部署蓝色和绿色两套环境
- 通过 Service selector 切换流量
- 验证回滚效果
金丝雀发布实践
- 使用 Nginx Ingress Canary 配置
- 逐步调整流量比例(10% → 30% → 50% → 100%)
- 验证基于请求头的分流
课程总结
本阶段学习了 K8S 的高级发布策略:
| 策略 | 核心思想 | 适用场景 |
|---|---|---|
| 滚动更新 | 逐步替换 | 常规更新 |
| 蓝绿发布 | 两套环境切换 | 关键业务 |
| 金丝雀发布 | 渐进式流量切换 | 大规模系统 |
选择建议:
- 小团队、简单应用:滚动更新
- 大团队、关键业务:蓝绿发布
- 大规模用户、需要验证:金丝雀发布
K8S 实战课程总结
本课程通过云咖啡公司的业务发展,系统讲解了 K8S 运维的核心技能。
课程回顾
| 阶段 | 主题 | 核心技能 |
|---|---|---|
| 一 | 部署官网 | Pod、Deployment、Service |
| 二 | 应用升级 | 滚动更新、健康检查 |
| 三 | 订单系统 | ConfigMap、Secret、PVC、StatefulSet |
| 四 | 前后端分离 | Ingress、多服务通信 |
| 五 | 高可用架构 | HPA、Redis、负载均衡 |
| 六 | 监控日志 | Prometheus、Grafana |
| 七 | 自动化部署 | Helm、CI/CD |
| 八 | 安全加固 | RBAC、NetworkPolicy、Pod安全 |
| 九 | 生产运维 | 资源配额、审计日志、故障排查 |
| 十 | 高级发布策略 | 滚动更新、蓝绿发布、金丝雀发布 |
持续学习方向
- K8S 网络深入(CNI、Service Mesh)
- K8S 安全最佳实践
- 多集群管理
- GitOps 实践