结合一个实例,具体讲讲手动金丝雀
还是用 fleet-api 举例,场景是:v1 已经在跑,v2 新增了一个 /stats 接口,想先放 10% 流量验证。
第一步:理解当前状态
fleet-api Service (selector: app=fleet-api)
↓
fleet-api-v1 Deployment(3个Pod,label: app=fleet-api, version=v1)
Service 通过 app=fleet-api 这个 label 找到所有 Pod。
第二步:创建 v2 Deployment,只跑 1 个副本
yaml
# deployment-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: fleet-api-v2 # 新名字,和 v1 的 Deployment 并列存在
namespace: fleet
spec:
replicas: 1 # 只起 1 个,总共 3+1=4 个 Pod,25% 流量到 v2
selector:
matchLabels:
app: fleet-api # 和 Service selector 一致,会被 Service 选中
version: v2
template:
metadata:
labels:
app: fleet-api # 这个 label 让 Service 能找到它
version: v2
spec:
containers:
- name: fleet-api
image: fleet-api:v2
bash
kubectl apply -f deployment-v2.yaml -n fleet
此时集群状态:
Service (app=fleet-api)
├── fleet-api-v1: Pod Pod Pod (3个,75%流量)
└── fleet-api-v2: Pod (1个,25%流量)
第三步:观察 v2 是否正常
bash
# 看 v2 的 Pod 日志 kubectl logs -n fleet -l version=v2 -f # 看错误率(多打几次请求观察) for i in $(seq 1 20); do curl -s http://fleet.local/vehicles; done # 看 v2 Pod 有没有重启 kubectl get pods -n fleet -w
观察 30 分钟到几小时,确认没有报错、没有崩溃。
第四步:逐步扩大 v2 比例
bash
# 没问题,v2 扩到 3 个,v1 缩到 1 个(75% 流量到 v2) kubectl scale deployment fleet-api-v2 -n fleet --replicas=3 kubectl scale deployment fleet-api-v1 -n fleet --replicas=1 # 再观察一段时间,完全没问题,v2 全量,v1 缩到 0 kubectl scale deployment fleet-api-v2 -n fleet --replicas=4 kubectl scale deployment fleet-api-v1 -n fleet --replicas=0
第五步:确认稳定后清理 v1
bash
kubectl delete deployment fleet-api-v1 -n fleet
如果 v2 出问题,回滚极简单:
bash
# v2 立刻缩到 0,流量全回 v1 kubectl scale deployment fleet-api-v2 -n fleet --replicas=0
这就是手动金丝雀的好处——v1 一直在,回滚就是一条命令,秒级完成。
