Appearance
蓝绿与金丝雀发布
Deployment 原生滚动更新适合常规发布——换镜像、逐批替换、readinessProbe 控制节奏。但它的回滚是逐批重建旧 Pod,不是瞬间切换。发布涉及接口改动、依赖变更、核心链路时,蓝绿或金丝雀更安全。
| 方式 | 核心动作 | 回退速度 | 适合场景 |
|---|---|---|---|
| 滚动更新 | 新旧 Pod 分批替换 | 慢——逐批回滚旧版本 | 常规无状态服务 |
| 蓝绿部署 | 两套完整版本并存,入口一次切换 | 快——改 selector 或路由即切回 | 需要秒级回退的服务 |
| 金丝雀发布 | 小比例流量进新版本,观察后逐步放大 | 快——调回权重即切回 | 风险较高、需要灰度验证的发布 |
Service selector 蓝绿
蓝绿部署的核心是两套 Deployment 同时存在,Service 通过 label 控制指向哪套。
部署蓝绿两套:
yaml
# blue Deployment——当前稳定版本
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-blue
namespace: demo
spec:
replicas: 3
selector:
matchLabels:
app: web
color: blue
template:
metadata:
labels:
app: web
color: blue
spec:
containers:
- name: web
image: harbor.example.com/demo/web:v1.0.0
---
# green Deployment——新版本
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-green
namespace: demo
spec:
replicas: 3
selector:
matchLabels:
app: web
color: green
template:
metadata:
labels:
app: web
color: green
spec:
containers:
- name: web
image: harbor.example.com/demo/web:v1.1.0部署 green 之后,两个版本的 Pod 都在运行,但 Service 还指向 blue——此时 green Pod 在跑但不接流量。先确认 green Pod Ready,再切流:
yaml
apiVersion: v1
kind: Service
metadata:
name: web
namespace: demo
spec:
selector:
app: web
color: blue # 切流时改成 green
ports:
- port: 80
targetPort: 8080切流和回滚就是改 Service selector:
bash
# 切到 green
kubectl -n demo patch svc web \
-p '{"spec":{"selector":{"app":"web","color":"green"}}}'
# 回滚到 blue
kubectl -n demo patch svc web \
-p '{"spec":{"selector":{"app":"web","color":"blue"}}}'切流是瞬间的——Service 的 EndpointSlice 立即更新为 green Pod 的 IP。但已建立的 TCP 连接不受影响,长连接可能还会在旧 Pod 上持续一段时间。切换前要确认新版本容量足够、缓存已预热、数据库 schema 兼容。
Gateway API 权重金丝雀
Gateway API 的 HTTPRoute 支持权重分流,不需要改 Service selector:
yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web
namespace: demo
spec:
parentRefs:
- name: main-gateway
namespace: gateway-system
hostnames:
- web.example.com
rules:
- backendRefs:
- name: web-v1
port: 80
weight: 90
- name: web-v2
port: 80
weight: 10权重随机分配,不保证同一用户的连续请求落在同一版本。需要会话亲和时配合 Header 匹配或 Cookie 机制。
逐步放量:weight: 10 → 观察指标 → weight: 50 → 观察 → weight: 100。观察窗口里至少看:5xx 比例、P95/P99 延迟、业务错误日志、下游数据库和缓存连接数。
Argo Rollouts
手动改 HTTPRoute 权重或 Service selector 时,发布节奏完全靠操作者控制。Argo Rollouts 把蓝绿、金丝雀、暂停、自动分析声明成控制器——发布过程受控制器约束,每一步有超时和自动回滚:
yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: web
namespace: demo
spec:
replicas: 4
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: harbor.example.com/demo/web:v1.1.0
strategy:
canary:
steps:
- setWeight: 10
- pause: {duration: 5m}
- setWeight: 50
- pause: {duration: 10m}
- setWeight: 100bash
kubectl argo rollouts get rollout web -n demo -w
kubectl argo rollouts promote web -n demo # 手动推进到下一步
kubectl argo rollouts abort web -n demo # 中止发布核心服务做灰度时,Argo Rollouts 比手工改权重更稳——发布过程受控制器约束,每步有固定观察窗口,异常时自动回滚。
Ingress 注解灰度
Ingress 控制器的金丝雀靠注解实现。这套方式依赖控制器私有实现:
yaml
metadata:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"社区维护的 ingress-nginx 已于 2026 年 3 月退役。旧集群如果依赖大量 Nginx 注解,迁移前先列出注解清单,再找 Gateway API 或目标控制器的对应能力。
金丝雀发布观察指标
| 指标 | 看什么 |
|---|---|
| 5xx 比例 | 新版本是否产生服务端错误 |
| 4xx 异常变化 | 路由、鉴权、参数兼容问题 |
| P95/P99 延迟 | 性能回退 |
| Pod 重启和 OOM | 运行时稳定性 |
| 应用错误日志 | 业务异常 |
| 下游连接数 | MySQL、Redis、MQ 是否被新版本打满 |
发布复盘里写清楚镜像 tag、流量比例、观察时间、指标变化、是否回滚。"灰度正常"四个字没有排查价值。