直接回答:kubectl describe pod 的 events 会直接给出原因,常见四类:镜像名或标签不存在(拼写错误、latest 被覆盖、镜像没推上去)、认证失败(私有仓库缺 imagePullSecret 或 Secret 过期)、网络问题(节点拉不通仓库,DNS、代理、防火墙)、仓库限流(Docker Hub 匿名配额)。events 里的 401/not found/dial timeout 分别对应前三类。

展开解析:逐项排法:镜像名错误——复制 events 里的完整镜像引用到能联通的机器 docker pull 验证,注意架构问题(ARM 节点拉 AMD64-only 镜像报 no matching manifest);私有仓库认证——确认 imagePullSecrets 挂对且在同一 namespace(Secret 不跨命名空间),用 kubectl get secret xxx -o yaml 看 .dockerconfigjson 内容是否过期,云厂商的临时凭证(ECR token 12 小时过期)要配自动刷新 controller;网络问题——kubectl debug node 或直接在节点上 curl 仓库地址,企业代理场景确认 containerd 的 registry mirror 与代理配置(K8s 层的 proxy env 不影响 kubelet 拉镜像这个坑常见);限流——Docker Hub 报 toomanyrequests,配 mirror 或认证后配额翻倍。预防手段:禁用 latest 标签生产使用(不可复现且缓存语义混乱),用 digest 锁定(image@sha256:...)保证不可变;大规模集群部署 registry 代理缓存(Harbor proxy cache)同时解决限流与外网依赖;imagePullPolicy 默认策略要懂——标签是 latest 时 Always,否则 IfNotPresent,这解释了为什么推了同名新镜像节点还在跑旧的。

追问方向:containerd 的镜像垃圾回收会不会误删在用镜像?多架构镜像 manifest list 如何工作?

(约 490 字)