canary vs 滚动更新
Source: Dev.to
(请提供您希望翻译的正文内容,我将为您翻译成简体中文,并保持原有的格式、Markdown 语法以及技术术语不变。)
Kubernetes 中的流量路由
Kubernetes 按 Pod IP 路由流量,而不是按百分比。
一个 Service(虚拟 IP)会将请求转发到任意就绪的 Pod;它并不知道以下信息:
- 应用版本
- 风险等级
- 流量百分比
User
↓
Service (virtual IP)
↓
Random Pod IP
如果你有 10 个 Pod,并且新增了一个 Pod(v2),此时共有 11 个 Pod。Service 可能会把 同一用户的所有请求 发送到同一个 Pod(连接复用),于是该用户的所有请求都可能命中 v2。因此,单个 Pod 接收到的流量比例可能在 0 % 到 80 % 之间波动。
Kubernetes 对哪些 Pod 会收到新代码、以及会影响多少用户 不作任何承诺。
滚动更新
- Pods 不会一次性全部终止。
- 整体容量保持可用。
它们 不保证:
- 哪些用户会获得新版本。
- 受影响的用户数量。
- 错误会被限制。
因此,滚动更新是 可用性安全 的,而不是 用户安全 的。
示例场景
- v1 正常工作,v2 引入了一个令牌验证错误。
- 启动了一个 v2 pod。
- 第一个真实用户请求该 pod → 登录失败。
- 用户重试 → 同一个 pod(会话粘性) → 用户被锁定。
- 提交支持工单,部署回滚,但损害已然发生。
即使是一次失败,也可能对认证或支付系统造成灾难性影响。
Source: …
金丝雀部署
金丝雀部署 不依赖随机性。你需要明确指定新版本的流量份额,例如:
- “仅 5 % 的流量进入 v2。”
在 1 000 次请求中:
- 950 → v1
- 50 → v2
这是一种 强制路由,而不是 “也许” 或 “如果运气好”。
实现方式
- 带权重路径的 Ingress 规则
- 负载均衡器的权重设置
- Service‑mesh 流量分割
基于副本的金丝雀(不是真正的百分比)
4 v1 pods
1 v2 pod
仅使用副本只能 降低概率;它 不能保证 流量限制。因此生产环境会使用显式的流量权重。
好处
- 如果 v2 pod 遇到外部超时(例如 Stripe API),只有少量金丝雀流量受到影响。
- 延迟峰值会被提前发现;金丝雀可以被停止,从而保障 99 % 的用户安全。
比较:滚动更新 vs. 金丝雀发布
| 方面 | 滚动更新 | 金丝雀发布 |
|---|---|---|
| 谁会获得新版本? | 任何人(随机) | 仅选定流量(受控) |
| 流量份额 | 随机分配 | 受控比例 |
| 风险规模 | 未知 | 已知且有限 |
| 回滚损害 | 已发生(可能很大) | 最小(有限曝光) |
| 典型使用场景 | 安全、低风险的更改 | 风险大或高影响的更改 |
Source: …
就绪探针
就绪探针只回答一个问题:
“Kubernetes 是否应该向该 Pod 发送流量?”
它仅检查技术可用性(进程存活、端口打开、HTTP 200 等),不验证业务逻辑、延迟、外部依赖或正确性。
常见的探针定义
readinessProbe:
httpGet:
path: /health
port: 8080
# or
readinessProbe:
tcpSocket:
port: 8080
- 探针通过 → pod 被标记为 Ready 并加入 Service。
- 探针失败 → pod 从 Service 中移除。
一个 pod 可能在 /health 上返回 200 OK,但其核心功能(例如支付、Kafka 消费)已经出现故障。
金丝雀部署的工作原理
- 就绪 – Pod 通过就绪探针 → 成为可接收流量的对象。
- 金丝雀流量(例如,5 %) – 请求被路由到新版本。
- 监控 – 观察真实用户行为、延迟、错误率以及外部系统响应。
- 决策
- 如果指标健康 → 增加流量份额。
- 如果错误超过阈值 → 停止金丝雀,保留稳定版本。
没有金丝雀,100 % 的流量将会暴露于任何缺陷。
Source: …
面试式摘要
- 就绪探针 用于验证 Pod 是否在技术上已经准备好接收流量。
- 金丝雀部署 通过向受控的真实流量子集暴露新版本并观察其行为,来确认 新版本对用户是安全的。
两种机制是互补的:
- 就绪 保护 Kubernetes 控制平面不向未运行的 Pod 发送流量。
- 金丝雀 保护业务和用户免受功能回退的影响。
可以这样理解:
- 就绪 = “发动机启动了吗?”
- 金丝雀 = “这辆车在高速行驶时是否安全?”