Kubernetes原生灰度部署可通过Service selector匹配多Deployment实现,但仅适用于粗粒度流量、无状态用户及可接受副本扰动的场景;需共享公共label、版本独立label,流量比≈副本比;精度要求高时应使用Ingress或服务网格。

用 Kubernetes 原生能力做灰度部署,**不依赖 Istio 或 Ingress 控制器也能生效,但仅适用于流量比例粗粒度、用户无状态、且能接受副本数扰动的场景**。一旦你需要 1% 流量、固定用户粘性、或自动扩缩不影响灰度比,就得切到服务网格或 Ingress 插件。
Service selector 同时匹配多个 Deployment 的 label
这是最轻量的灰度实现方式:让一个 Service 的 selector 同时命中 v1 和 v2 版本的 Pod,靠副本数控制流量权重。
- 两个
Deployment必须共享至少一个公共 label(如app: myapp),否则Service无法同时选中它们 - v1 和 v2 需各自带版本 label(如
version: v1/version: v2),方便后续单独操作 -
Service的selector只写公共 label,不写version—— 写了就只匹配一个版本 - 流量比例 ≈
v1 replicas:v2 replicas,但实际受 kube-proxy 随机调度影响,不是严格百分比
示例 Service 片段:
spec:
selector:
app: myapp # 不包含 version用 nginx.ingress.kubernetes.io/canary-weight 控制流量比例
如果你集群已部署 ingress-nginx,且版本 ≥ 0.21.0,就能直接用 annotation 实现更精确的灰度,无需改 Service 或副本数。
评估 Kubernetes 集群安全态势,覆盖 RBAC、工作负载安全、网络策略、基础设施即代码(IaC)、运行时监控和密钥管理等 30 项控制项……
- 必须定义两个独立的
Ingress资源:主入口(canary: false)和灰度入口(canary: true) - 灰度
Ingress必须加 annotation:nginx.ingress.kubernetes.io/canary: "true"和nginx.ingress.kubernetes.io/canary-weight: "5" - 权重范围是 0–100,代表该
Ingress接收的请求百分比;注意它只对同一 host + path 生效 - 不能和
canary-by-header或canary-by-cookie混用,否则按优先级规则 fallback,容易误判
常见错误:canary-weight 设为 0 后仍收到灰度流量 —— 实际是因 header 或 cookie 规则优先级更高,需检查是否残留其他 canary annotation。
蓝绿切换时修改 Service selector 的风险点
蓝绿本质是“全量切换”,但用 Service 切换时,selector 修改会触发 endpoint 重建,可能造成秒级连接中断。
- 不要直接
kubectl edit service改selector,应使用kubectl patch原子更新,减少窗口期 - 确保新版本
Deployment的 Pod 已全部Running/Ready,再改Service,否则 endpoint 为空导致 503 - 若用
ClusterIP类型,客户端 DNS 缓存可能导致部分请求仍打到旧 endpoint,建议搭配 readinessProbe + 客户端重试逻辑 - 此方式无法回滚到“某个中间灰度态”,只能在 v1 ↔ v2 之间二选一
真正难的不是配置怎么写,而是当 HPA 自动把 v2 副本从 1 扩到 10,你原来设的 1:3 流量比就彻底失效了——这时候 label selector 方案就失守了。所以只要灰度策略有精度要求或生命周期要长期维护,就别硬扛原生 Service,早点接入 VirtualService 或 Gateway 这类声明式流量层。

















