Helm 升级后 Pod 起不来,别急着删了重装。九成问题集中在三类:镜像拉取失败、升级被中断导致 release 卡死、资源不足或探针配错。最快的排障顺序是先 helm status 看清 release 处在什么状态,再用 kubectl describe pod 读 Events。下面按这个顺序把每一步的真实命令和判断标准列清楚,照着跑基本能定位。
一、先看清 release 卡在哪一步
升级失败不等于业务容器坏了,很多时候是 Helm 这层先卡住。先执行两条:
helm status myapp -n prod
helm history myapp -n prod
看 STATUS 字段:如果是 FAILED 或 pending-upgrade,说明 Helm 没把 manifest 正确落库,问题在发布流程而非业务 Pod。这时直接 kubectl get pods -n prod 通常会看到 Pod 卡在 Pending,或者旧版本在跑、新版本一直起不来。先记下列表里 REVISION 和 LAST DEPLOYED,后面回滚要用。
二、场景一:镜像拉不下来(ImagePullBackOff)
这是最高频的原因。执行 kubectl describe pod myapp-xxx -n prod,翻到 Events 末尾,出现 Failed to pull image 就是它。三种根因,按出现概率排:
- 镜像 tag 写错或不存在:
helm get manifest myapp -n prod | grep "image:"核对仓库地址和 tag; - 私有仓库没配 pull secret:在 values.yaml 里加
imagePullSecrets,或手动建一个:kubectl create secret docker-registry regcred --docker-server=registry.example.com --docker-username=u --docker-password=p -n prod; - 节点到仓库网络不通:登录节点
docker pull 镜像全名手动验证,能拉下来才说明是配置问题。
kubectl describe pod myapp-7d9c8b6f4-abcde -n prod | tail -20
三、场景二:升级被中断,release 卡在 pending-upgrade
终端被关、SSH 断了、Ctrl-C 了,都会留下一个不完整的 release。表现:再跑一次 helm upgrade 报 another operation is in progress。处理顺序:
# 回滚到上一个能用的版本(0 = 最近一次成功 revision)
helm rollback myapp 0 -n prod
# 或指定具体版本号
helm rollback myapp 2 -n prod
# 强行覆盖卡死状态(慎用,会重建部分资源)
helm upgrade myapp ./my-chart -n prod --force
如果 rollback 也失败,且确认集群里该 release 的资源可以丢弃,再 helm uninstall myapp -n prod 后重装。生产环境别上来就 uninstall,先 rollback。
踩坑实录
上周给 prod 升 myapp,SSH 终端断了,release 卡在 pending-upgrade。我直接再跑 helm upgrade 报 “another operation is in progress”,kubectl get pods 却显示旧版本还在跑。一开始想 uninstall 重来,被同事拦下。改成 helm rollback myapp 0 -n prod,约 10 秒回到上一个正常 revision,业务零中断。教训:升级中断先 rollback,别急着卸载。
四、场景三:资源不够或探针失败(Pending / CrashLoopBackOff)
镜像拉到了却起不来,看 kubectl get pods -n prod 的状态列:
- Pending:
kubectl describe pod看 Events,多半是 CPU/内存 request 超过节点余量,或 PVC 的存储类不存在。用kubectl top nodes看资源余量; - CrashLoopBackOff:
kubectl logs myapp-xxx -n prod --previous看崩溃前日志,常见是环境变量漏传(应用要 DATABASE_URL 但 values 里没给)、非 root 用户却要写只读目录、容器监听端口和 spec 对不上; - Ready 一直 0/1:liveness/readiness 探针阈值太严或路径错,先在 values 里放宽
initialDelaySeconds再升。
一张表理清排查顺序
| 现象 | 先跑的命令 | 命中的根因 |
|---|---|---|
| release 状态异常 | helm status / history |
FAILED / pending-upgrade |
| Pod 镜像拉取失败 | kubectl describe pod |
tag 错 / 缺 pull secret |
| Pod 一直重启 | kubectl logs --previous |
环境变量 / 端口 / 权限 |
kubectl top nodes |
资源 request 超节点 |
三个判断卡片
排障步骤流程
helm status 看状态
describe pod 读 Events
按根因修(镜像/资源)
rollback 0 兜底
常见问题
helm rollback 0 里的 0 是什么意思?
0 代表”最近一次成功的 revision”,不是版本号 0。指定具体数字(如 2)则回滚到那一次发布。回滚本身会生成一条新的 revision 记录,不会丢失历史。
升级卡住后能直接 helm uninstall 吗?
能,但不建议作为第一步。uninstall 会删掉 release 名下所有资源,如果集群里还有别的控制器引用这些资源就会出错。优先用 rollback,确认无可挽回再 uninstall。
怎么避免升级中途断网留烂摊子?
加 --wait --timeout 10m 让 Helm 等所有资源 Ready 再返回;CI 里用 --atomic,升级失败会自动回滚,比手动处理省心。
如果这篇帮你少删了一次 release,欢迎在 fenij.com 留言,说说你踩过的 Helm 升级坑。