阿里云 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,别指望节点主动拉新。这类问题最好一次改到位,反复小改反而容易把原因搅混。
