4. Kubernetes 资源版本管理:Deployment、StatefulSet、DaemonSet 的更新策略与 Revision 历史机制
在基于 Helm 的发布流水线中,回滚操作的核心依赖是 Kubernetes 工作负载资源的版本管理能力。Deployment、StatefulSet 和 DaemonSet 各自拥有不同的更新策略与 Revision 历史机制,理解这些差异是设计可靠回滚策略的前提。
4.1 更新策略对比
三种工作负载资源支持不同的更新策略,直接影响回滚时的行为与速度。
| 资源类型 | 默认更新策略 | 可选策略 | 回滚粒度 |
|---|---|---|---|
| Deployment | RollingUpdate | Recreate | Pod 级别,支持逐步回滚 |
| StatefulSet | RollingUpdate | OnDelete | Pod 级别,按序回滚 |
| DaemonSet | RollingUpdate | OnDelete | 节点级别,逐节点回滚 |
关键差异: Deployment 支持
maxSurge 和 maxUnavailable 参数控制滚动速率;StatefulSet 按 Pod 序号从高到低更新;DaemonSet 按节点逐个更新。这些差异决定了回滚时的 Pod 替换顺序与并发度。
4.2 Revision 历史机制
Kubernetes 通过 ControllerRevision 资源记录每个工作负载的版本历史。每次 Pod 模板发生变化时,系统会自动创建一个新的 Revision,并保留历史版本用于回滚。
# 查看 Deployment 的 Revision 历史
kubectl rollout history deployment/nginx-deployment
# 输出示例
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
注意: 默认情况下,Kubernetes 只保留 10 个 Revision。超过限制后,最旧的 Revision 会被自动清理。在生产环境中,建议根据回滚需求调整
revisionHistoryLimit 参数。
4.3 Revision 历史管理参数
| 参数 | 默认值 | 说明 |
|---|---|---|
revisionHistoryLimit |
10 | 保留的 Revision 数量上限 |
change-cause |
无 | 通过 annotation 记录变更原因 |
rollback-to |
无 | 指定回滚的目标 Revision |
4.4 更新策略与 Revision 关系图
4.5 三种资源的更新策略详解
4.5.1 Deployment 更新策略
Deployment 支持两种更新策略:
- RollingUpdate(默认): 逐步替换旧 Pod,支持
maxSurge(最大超出期望副本数)和maxUnavailable(最大不可用副本数)参数控制滚动速率。 - Recreate: 先删除所有旧 Pod,再创建新 Pod,适用于无法同时运行两个版本的场景。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
revisionHistoryLimit: 15 # 保留 15 个 Revision
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
annotations:
kubernetes.io/change-cause: "升级到 nginx:1.21" # 记录变更原因
spec:
containers:
- name: nginx
image: nginx:1.21
4.5.2 StatefulSet 更新策略
StatefulSet 支持两种更新策略:
- RollingUpdate(默认): 按 Pod 序号从高到低逐个更新,保证有状态应用的顺序性。
- OnDelete: 仅当手动删除 Pod 后才触发更新,适用于需要精确控制更新时机的场景。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 3
revisionHistoryLimit: 10
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 0 # 分区更新,0 表示全部更新
template:
spec:
containers:
- name: mysql
image: mysql:8.0
分区更新: StatefulSet 支持
partition 参数,只有序号大于等于 partition 的 Pod 才会被更新。这在灰度发布和回滚中非常有用。
4.5.3 DaemonSet 更新策略
DaemonSet 支持两种更新策略:
- RollingUpdate(默认): 逐节点更新 DaemonSet Pod,支持
maxSurge和maxUnavailable参数。 - OnDelete: 仅当手动删除 Pod 后才触发更新。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
spec:
revisionHistoryLimit: 5
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 最多 1 个节点不可用
template:
spec:
containers:
- name: fluentd
image: fluentd:v1.14
4.6 Revision 历史操作命令
| 操作 | 命令 | 说明 |
|---|---|---|
| 查看历史 | kubectl rollout history deployment/<name> |
列出所有 Revision 及变更原因 |
| 查看详情 | kubectl rollout history deployment/<name> --revision=<N> |
查看指定 Revision 的详细信息 |
| 回滚到上一版本 | kubectl rollout undo deployment/<name> |
回滚到上一个 Revision |
| 回滚到指定版本 | kubectl rollout undo deployment/<name> --to-revision=<N> |
回滚到指定 Revision |
| 查看回滚状态 | kubectl rollout status deployment/<name> |
监控回滚进度 |
4.7 Revision 历史与 Helm Release 的关系
4.8 回滚策略设计建议
最佳实践:
- 设置合理的
revisionHistoryLimit,建议 15-20 个,平衡存储与回滚需求 - 使用
change-causeannotation 记录每次变更原因,便于快速定位回滚目标 - StatefulSet 优先使用分区更新进行灰度发布,降低回滚风险
- DaemonSet 设置
maxUnavailable: 1确保节点级回滚的稳定性 - 定期清理无用的 Revision 历史,避免 Secret/ConfigMap 引用过期
常见陷阱:
- Revision 历史被自动清理后,无法回滚到被清理的版本
- Helm 回滚不会自动清理 Kubernetes 中多余的 Revision
- StatefulSet 回滚时 Pod 序号不会重置,可能导致数据不一致
- DaemonSet 回滚需要逐节点进行,耗时较长