一、StatefulSet 扩缩容为什么要比 Deployment 更谨慎¶
StatefulSet 同样支持改 replicas,也支持 kubectl edit、kubectl scale 和 kubectl patch,但它的扩缩容过程带有明确顺序。
kubectl edit sts web
kubectl scale sts web --replicas=5
kubectl patch sts web -p '{"spec":{"replicas":3}}'
扩容时,Pod 会按照序号逐个补齐;缩容时,则会从最大序号开始逐个回收。对于带状态业务来说,这种串行行为恰恰是价值所在。
二、OnDelete 和 RollingUpdate 有什么区别¶
1.1 OnDelete:你不删,我不更¶
OnDelete 是很保守的更新模式。即使你修改了 StatefulSet 的 Pod 模板,控制器也不会主动替换 Pod,只有你手动删除某个 Pod,它才会按新模板重建。
spec:
updateStrategy:
type: OnDelete
实操流程通常像这样:
kubectl replace -f stateful-ondelete.yaml
kubectl get pods -l app=nginx -oyaml | grep image
kubectl delete pod web-1
kubectl get pods -l app=nginx -oyaml | grep image
这类策略适合特别谨慎的状态服务,便于你“一台一台、一个序号一个序号”地验证。
1.2 RollingUpdate:默认的自动滚动¶
如果采用 RollingUpdate,StatefulSet 会按序号逆序进行更新,高序号 Pod 会先替换。
kubectl replace -f stateful.yaml
kubectl get pods -l app=nginx -oyaml | grep image
这意味着你要提前确认:
- readiness 是否足够准确
- 新版本是否兼容旧数据
- 高序号实例先更新是否符合业务预期
三、如何用 partition 做 StatefulSet 灰度发布¶
StatefulSet 也可以做分段更新,关键配置是:
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 3
replicas: 5
当 partition: 3 时,只有序号大于等于 3 的 Pod 会更新,也就是 web-3 和 web-4。低于这个分区号的 Pod 即使被删除,也会按照旧版本模板重建。
这类配置非常适合:
- 先更新少量高序号实例做验证
- 按阶段逐步推进版本
- 做最小范围金丝雀发布
四、回滚能不能用,怎么用¶
StatefulSet 同样支持 rollout history 和 rollout undo:
kubectl rollout history sts web
kubectl rollout undo sts web
kubectl rollout undo sts web --to-revision=2
原文也特别提醒了一点:真实生产里,StatefulSet 一般不会像 Deployment 那样频繁回滚。原因很简单,镜像可以回去,数据状态未必能一起回去。所以回滚命令能用,不代表业务上一定安全。
五、删除 StatefulSet 时,级联和非级联差别很大¶
删除 StatefulSet 主要有两种方式。
非级联删除:
kubectl delete statefulset web --cascade=false
这种方式会删除 StatefulSet 对象,但保留现有 Pod。保留下来的 Pod 会变成“孤儿 Pod”,后续再删掉它们时,不会自动重建。
级联删除:
kubectl delete sts web
这种方式会把 StatefulSet 和它管理的 Pod 一并删除。
最后还要额外记住一条:无论是删除还是缩容,StatefulSet 关联的存储通常不会自动清掉。对数据服务来说,这是一种保护;对运维来说,也意味着你必须对卷和数据生命周期单独负责。