DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

StatefulSet 回退镜像后,坏版本 Pod 仍卡住更新

模板已回退,坏镜像 Pod 仍挡住 StatefulSet 更新:核对 revision、策略与分区,先恢复好模板,再正常终止已确认的坏实例。

StatefulSet 更新到了不存在的镜像,某个 Pod 停在 ErrImagePull 或 ImagePullBackOff。把模板中的镜像恢复成可用版本后,这个 Pod 仍在尝试拉取坏镜像,其他实例也没有继续更新。对使用 RollingUpdate 和默认 OrderedReady 的 StatefulSet,模板回退与已经创建的坏版本 Pod 需要分别处理。

控制器等待更新中的 Pod 达到 Running、Ready,才继续推进。在这个失败回退场景中,只恢复模板可能不足以解除等待;还需要在模板已经恢复后,按正常终止流程移除控制器此前用坏配置创建的 Pod,让它重新创建实例。

先确认卡住的是哪一个版本

下面为只读检查示例,名称、标签与命名空间要替换:

kubectl get statefulset web -n team-app -o yaml
kubectl get pods -n team-app -l app=web -o wide
kubectl describe pod web-2 -n team-app
kubectl get pod web-2 -n team-app -o yaml

对照 StatefulSet 当前的 Pod 模板镜像、更新策略,以及失败 Pod 的实际镜像和 controller-revision-hash。对象的模板已经改回好版本,不等于旧 Pod 的配置也被修改。先确定哪些 Pod 确实来自失败版本,不要按编号猜测,也不要一次删除所有实例。

还要核对 updateStrategy.rollingUpdate.partition。分区更新会影响哪些序号采用新模板;低于分区边界的 Pod 即使被删除,也可能仍按旧版本重新创建。采用 OnDelete 或其他策略时,也不能照搬默认滚动更新的判断。

如果事件显示的是 Multi-Attach、存储供应失败或节点不可用,应先沿该故障处理。这里针对坏配置造成实例始终无法就绪、回退又被该实例挡住的路径;单副本 Deployment 的卷并存冲突是另一种更新问题。

恢复模板在前,移除坏实例在后

先保存当前清单、失败版本和此前可用版本,确认数据备份及应用的恢复流程。通过实际的 GitOps、Operator 或发布配置恢复已验证的好模板,避免只在集群中临时编辑,随后又被管理控制器改回坏配置。

核对集群里的模板已经恢复,分区和其他更新条件符合预期后,再逐个处理明确来自坏版本的 Pod。下面是普通删除一个已核定坏实例的示例,并非批量恢复命令:

kubectl delete pod web-2 -n team-app

使用前确认它确实属于目标 StatefulSet、终止该实例符合业务要求,且旧进程和写入者能够正常退出。保留正常宽限期,等待旧实例终止和卷释放,再观察控制器补建的新实例。不要追加 --force、零宽限期或清除 finalizer 来跳过真实终止。

节点失联时,删除 Kubernetes 对象并不能证明节点上的进程已经停止。涉及有状态写入,应先按存储与应用的恢复规则隔离旧写入者,避免同一身份或同一数据出现双写。本文的处理不删除 PVC、PV,也不清空数据目录。

新策略需要单独评估

不要把切换 Parallel 当成通用回退修复。它与实例管理和更新并发有关,不会自动证明坏版本已经替换、存储可用或应用支持并发重建。

Kubernetes 1.37 新增的 StatefulSet Recreate 仍是默认关闭的 alpha 功能,需要在 API server 与 controller manager 启用 StatefulSetRecreateStrategy。它在更新时删除全部 Pod,等它们终止后才重建,会造成全副本停机。升级到该版本并不表示普通 RollingUpdate 的失败回退路径自动改变,不应在故障中直接改策略来试运气。

确认恢复的是可用实例

新 Pod 创建后,确认实际镜像与预期模板一致,卷和数据正确,就绪探针通过,业务读写恢复,后续实例按当前策略继续更新。若它又回到相同坏镜像,重新核对模板管理者、分区及实际 revision;若镜像正确但仍未就绪,检查新的应用或存储错误。

回退配置不会撤销数据库迁移或磁盘格式变更。此前镜像是否还能读取当前数据,需要按应用的版本兼容规则确认;涉及数据恢复时,使用已验证的备份流程,不能只凭 Pod 重新 Running 就结束恢复。