Kubernetes 推送了新 latest,apply 却显示 unchanged:镜像更新没有改变 Pod 模板
仓库覆盖 latest 后 Deployment apply 仍显示 unchanged 时,区分 Pod 模板、容器启动拉取策略和实际镜像,采用可追踪版本发布与回退。
新镜像已经覆盖仓库中的 latest,重新 kubectl apply 后 Deployment 仍显示 unchanged,应用继续运行旧代码。先检查提交的 .spec.template 是否真的变化;仓库标签指向了新镜像,并不会自动让 Deployment 替换正在运行的 Pod。
imagePullPolicy: Always 决定容器启动时如何请求镜像,不是定时检查仓库、自动发布新版本的开关。以下针对由 Deployment 管理的工作负载;自动镜像更新控制器、准入修改和 GitOps 流程还要核对其实际行为。
把模板镜像名与运行镜像分开查看
以下是只读检查示例,替换命名空间、Deployment 和 Pod 名称:
kubectl -n app get deployment web -o yaml
kubectl -n app get pods
kubectl -n app get pod web-example -o yaml
查看 Deployment 的容器名、完整 image、imagePullPolicy 和暂停状态,再核对实际 Pod 的创建时间、镜像字段及 status.containerStatuses 中的 imageID。多容器、多副本应用要逐个对应,不能从一个 Pod 的日志推断全部副本版本。
模板里仍是同一个 registry.example.com/team/web:latest,其他模板字段也没有变化时,Deployment 不会因为仓库里的内容变了就创建新修订。若模板已经变化却没有更新,应继续检查暂停状态、控制器事件及发布工具是否又覆盖了配置。
运行时的 imageID 表示具体镜像身份,其格式与运行时有关。多架构镜像还可能涉及索引与平台镜像摘要,不能把不同层次的摘要字符串直接相等比较;结合实际平台与仓库构建记录核对。
Always 只在启动容器时请求镜像
采用 Always 时,kubelet 每次启动容器都会请求运行时拉取镜像。运行时向仓库解析名称或标签的摘要,缺少的层才需要下载;节点已经有对应层时可以复用缓存。因此没有再次下载所有层,并不说明 Always 没生效。
但已经运行的容器不会因此改变代码。反过来,同一个可变标签被覆盖后,后来重建或启动的容器可能拿到新内容,而其余副本继续使用旧镜像,形成一套 Deployment 内的版本混用。
未显式填写拉取策略时,默认值在对象首次创建时确定:latest 或没有标签通常得到 Always,普通标签通常得到 IfNotPresent。后来把普通标签改成 latest,已有策略不会自动跟着改,应查实际对象字段。
正式发布使用可追踪的镜像身份
为本次构建保留独立且不再覆盖的版本标签,或使用准确镜像摘要,并在原发布入口更新容器的 image。下面只展示已有 Deployment 中的字段片段,保留其余配置:
containers:
- name: web
image: registry.example.com/team/web:release-20261005-1
imagePullPolicy: IfNotPresent
域名、路径和标签都是示例,目标镜像必须真实存在、适配节点平台并有访问权限。这里的 IfNotPresent 以发布标签不再覆盖为前提;无法保证标签稳定时,按交付策略选用摘要或明确拉取行为,不能把新标签也当成可反复覆盖的另一个 latest。
image 字段变化会改变 Pod 模板并触发更新。通过 Helm、Operator 或 GitOps 管理时,应修改实际管理的配置并保留镜像身份,临时手改线上对象可能在下次同步时被恢复。
开发环境确需复用标签,显式安排重建
若环境允许替换 Pod、且已核对实际拉取策略与仓库内容,可以按受控发布流程重新启动该 Deployment。示例:
kubectl -n app rollout restart deployment web
kubectl -n app rollout status deployment web
先评估副本数量、就绪检查、可用容量、更新策略和持久数据。restart 会替换 Pod,不保证应用无中断,也不会自动把 IfNotPresent 改为 Always。仓库不可达或权限错误时,新容器可能拉取失败,不要连续删掉所有旧 Pod。
如果更新期间又覆盖了同一个标签,不同容器仍可能拿到不同版本。显式 restart 可以解决本轮没有替换的问题,但无法提供可变标签的长期版本一致性。
回退需要旧镜像,而不只是旧标签文字
变更前保留原模板、可用镜像摘要及发布记录。Deployment 回退恢复的是 Pod 模板;旧修订中如果也写着 latest,仓库内容已经变了,回退后启动的容器仍可能拿到新镜像。
需要可靠回退时,恢复指向确切旧构建的标签或摘要,并确保它仍可拉取。镜像回退也不恢复数据库和外部配置,应遵守应用自身的兼容与数据恢复要求。
验收时核对所有目标副本对应的实际镜像、就绪状态和应用版本行为。apply 被接受、rollout 完成与目标代码已经运行,是需要分别确认的结果。


