文章目录
StatefulSet 更新策略详解
StatefulSet 是 Kubernetes 中用于管理有状态应用的控制器,它提供了两种更新策略:RollingUpdate
和 OnDelete
。下面我将详细讲解这些策略,特别是 RollingUpdate
策略中的 partition
和 maxUnavailable
参数。
1. StatefulSet 更新策略概述
StatefulSet 支持两种更新策略:
spec:
updateStrategy:
type: RollingUpdate # 或 OnDelete
1.1 OnDelete 策略
- 当更新策略设置为
OnDelete
时,StatefulSet 控制器不会自动更新 Pod - 只有在手动删除 Pod 后,控制器才会用新模板创建新的 Pod
- 这种方式提供了最大程度的控制,但需要手动干预
1.2 RollingUpdate 策略
- 默认策略,StatefulSet 控制器会自动删除并重建 Pod
- 更新是有序进行的(从最高序号到最低序号)
- 支持精细控制更新的参数:
partition
和maxUnavailable
2. RollingUpdate 策略详解
2.1 基本滚动更新行为
当使用 RollingUpdate
策略时:
- StatefulSet 从最高序号的 Pod 开始更新
- 每次更新一个 Pod,等待它进入 Running 和 Ready 状态后再更新下一个
- 如果更新过程中某个 Pod 失败,更新会暂停
2.2 partition 参数
partition
是 RollingUpdate 策略中最重要且独特的参数:
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 3 # 分区值
作用:
- 指定一个序号,只有序号大于或等于此值的 Pod 才会被更新
- 序号小于此值的 Pod 将保持不变
使用场景:
-
分阶段更新:先更新部分 Pod 进行测试,确认无误后再更新剩余 Pod
- 初始设置
partition: 3
(假设有 5 个副本) - 只有 Pod-4 和 Pod-5 会被更新
- 测试通过后,将
partition
改为 0 更新所有 Pod
- 初始设置
-
金丝雀发布:先更新少量 Pod 作为金丝雀
- 设置
partition
为副本数减一(如 4/5) - 只更新一个 Pod 进行验证
- 设置
-
回滚机制:如果更新后发现问题,可以增大
partition
值阻止进一步更新
示例流程:
# 初始 StatefulSet 有 5 个副本
kubectl apply -f statefulset.yaml
# 设置 partition=3,只有序号 >=3 的 Pod 会被更新
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":3}}}}'
# 更新镜像
kubectl set image statefulset/web nginx=nginx:1.9.1
# 此时只有 web-3, web-4 会被更新
# 确认无误后,设置 partition=0 更新所有 Pod
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":0}}}}'
2.3 maxUnavailable 参数 (Kubernetes 1.7+)
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 最大不可用数量
作用:
- 指定在更新过程中最多可以有多少个 Pod 不可用
- 可以设置为绝对值(如 1)或百分比(如 20%)
- 默认值为 1
行为特点:
- 控制并行更新的 Pod 数量
- 确保在更新过程中始终有足够数量的 Pod 提供服务
- 与 Deployment 的
maxUnavailable
类似,但实现方式不同
注意事项:
- 对于 StatefulSet,
maxUnavailable
的实际行为受有序性约束 - 即使设置
maxUnavailable
大于 1,StatefulSet 仍然会按序号逆序更新 - 它主要影响的是更新速度,而不是真正的并行更新
3. 更新策略对比
特性 | RollingUpdate | OnDelete |
---|---|---|
自动更新 | 是 | 否(需手动删除 Pod) |
更新顺序 | 逆序(从高序号到低序号) | 无顺序 |
精细控制 | 支持(partition, maxUnavailable) | 无 |
适用场景 | 需要自动滚动更新 | 需要完全手动控制 |
4. 实际应用建议
- 生产环境推荐:使用
RollingUpdate
结合partition
进行分阶段更新 - 关键系统:可以先更新少量 Pod(设置高 partition 值)进行验证
- 回滚策略:通过调整 partition 可以快速停止有问题的更新
- 性能敏感型应用:合理设置
maxUnavailable
平衡更新速度和服务可用性
5. 示例完整配置
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 5
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 3 # 只更新序号 >=3 的 Pod
maxUnavailable: 1 # 最多1个Pod不可用
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
name: web
通过合理配置这些参数,可以实现对 StatefulSet 更新的精细控制,确保有状态应用的平稳更新。