阿里云 ACK 1.26,节点 Ubuntu 22.04,Deployment 里 image 写的是 harbor.local/app:latest,imagePullPolicy 是 IfNotPresent,重新构建并推送同名 tag 后滚动更新,Pod 起来了但跑的还是旧代码,进容器看二进制时间戳没变。

原因不止一个,得分开看。IfNotPresent 发现本地已有同名 tag 就不再拉取;镜像 tag 用 latest,节点缓存和仓库指向不同 digest;节点 kubelet 的镜像回收没触发,旧层一直留着;滚动更新只重建 Pod,不会强制重新拉镜像。

上来先看 Pod 实际使用的镜像 digest

kubectl get pod -o jsonpath='{.items[*].status.containerStatuses[*].imageID}'

接着对比仓库里 latest 的 digest

docker manifest inspect harbor.local/app:latest | grep digest

然后改用唯一 tag 并更新 Deployment

kubectl set image deploy/app app=harbor.local/app:v20261111 --record

强制重建并确认新 digest

kubectl rollout restart deploy/app && kubectl rollout status deploy/app

同样的操作我在测试机上先走了一遍,线上只做验证过的部分。

这台环境是别人交接的,不少默认值被动过,只能一项项核。

同事提醒我看一下最近一次发布,时间点确实对得上。

恢复的判定其实很直接。新 Pod 的 imageID 与仓库 digest 一致,容器内二进制时间戳是新的,业务日志里出现新版本号。

提醒一点。latest 加 IfNotPresent 是最容易踩的组合,生产上应该用不可变 tag 或 digest,别指望节点主动拉新。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189