文章目录
-
- 一、标准做法:滚动更新参数控制(一次只换一个)
- 二、精准做法:灰度/金丝雀(只更新一个实例,独立验证)
-
- 1)原有稳定版(my-app-v1)
- [2)金丝雀版本(my-app-v2,仅 1 个实例)](#2)金丝雀版本(my-app-v2,仅 1 个实例))
- 3)流量控制(可选)
- [三、能不能"强制更新某个 Pod"?](#三、能不能“强制更新某个 Pod”?)
- 四、总结
在 K8s 里, Deployment 本身不支持"只更新某一个指定 Pod" (它是全模板更新、由 ReplicaSet 统一管理)。但你可以通过两种常用手段实现" 一次只更一个实例 / 先更一个实例验证 "的效果:
一、标准做法:滚动更新参数控制(一次只换一个)
通过 maxSurge=1、maxUnavailable=0,让 Deployment 每次只更新 1 个 Pod,更新完一个再换下一个。
1)配置示例(deployment.yaml)
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最多比期望数多 1 个(先启一个新的)
maxUnavailable: 0 # 更新时不允许有 Pod 不可用
template:
spec:
containers:
- name: my-app
image: my-app:v2 # 改这里触发更新
2)触发更新
bash
kubectl apply -f deployment.yaml
# 或
kubectl set image deployment/my-app my-app=my-app:v2
3)效果(replicas=3)
- 新建 1 个 v2 Pod(总数 4)
- 等它就绪 → 删除 1 个 v1 Pod(总数 3)
- 再新建 1 个 v2 → 再删 1 个 v1
- 直到全部变成 v2
👉 这是逐个更新,但不是"指定某一个 Pod",而是控制器按节点/调度策略选择旧 Pod 替换。
二、精准做法:灰度/金丝雀(只更新一个实例,独立验证)
如果必须只跑 1 个新版本实例、不影响旧版本 ,用独立 Deployment + 标签分流更稳妥。
1)原有稳定版(my-app-v1)
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-v1
spec:
replicas: 2
selector:
matchLabels:
app: my-app
version: v1
template:
metadata:
labels:
app: my-app
version: v1
spec:
containers:
- name: my-app
image: my-app:v1
---
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
selector:
app: my-app
ports:
- port: 80
2)金丝雀版本(my-app-v2,仅 1 个实例)
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-v2
spec:
replicas: 1 # 只跑 1 个
selector:
matchLabels:
app: my-app
version: v2
template:
metadata:
labels:
app: my-app
version: v2
spec:
containers:
- name: my-app
image: my-app:v2
3)流量控制(可选)
-
全部流量进 v1,手动/内部测试访问 v2(通过独立 Service 或端口转发)
-
验证没问题后:
bash# 扩容 v2 到 3,缩容 v1 到 0 kubectl scale deployment my-app-v2 --replicas=3 kubectl scale deployment my-app-v1 --replicas=0
三、能不能"强制更新某个 Pod"?
- 不推荐、也不稳定 :
- 直接
kubectl delete pod <指定pod>→ ReplicaSet 会重建一个新模板 Pod(相当于被动更新一个) - 但这不是"更新",是"删旧建新",且不能选镜像/版本,模板改了才会建新模板的
- 直接
四、总结
- 要逐个更新、不中断业务 :用
maxSurge=1, maxUnavailable=0的 RollingUpdate。 - 要只跑 1 个新版本、独立验证 :用金丝雀 Deployment(replicas=1)。