Kubernetes创建Pod时Containerd重复拉取相同镜像问题咨询
问题原因
首先澄清:你在ctr -n k8s.io i ls输出中看到的3条条目,底层镜像层仅存储1份,并非实际拉取了3份完整镜像,这些是同一个镜像实体的多个引用标识。该问题是旧版本containerd的已知Bug,大量Pod创建场景下确实会因元数据膨胀、冗余引用无法回收触发磁盘压力,具体原因如下:
- 前两条分别带标签、带
@sha256摘要的条目:1.4.8以前的containerd CRI组件存在逻辑缺陷,Kubelet按镜像名:标签触发拉取后,CRI会额外自动生成一条带摘要的引用条目,两条指向同一个镜像实体,属于冗余元数据。 - 第三条仅以
sha256:开头的无名条目:触发原因有两个:一是私有仓库中镜像的manifest list与对应单架构manifest的摘要不匹配,Kubelet镜像存在性校验时无法匹配到已有的标签/摘要引用,触发二次拉取生成无名引用;二是你使用的containerd版本镜像存在性校验逻辑存在漏洞,无法将按标签拉取的镜像和按摘要拉取的请求匹配到同一个镜像实体,从你提供的事件日志也能看到,同一时间触发了两次镜像创建请求,分别对应标签拉取和摘要拉取。
注:部分旧版本containerd的镜像垃圾回收逻辑不会清理这些无名引用,长期运行后冗余元数据会持续占用磁盘空间,甚至触发节点磁盘压力告警。
解决方案
- 升级containerd版本:优先升级到1.4.13+、1.5.10+、1.6.0+的稳定版本,上述版本已修复CRI镜像冗余引用生成、无名引用无法回收的问题,是最彻底的解决方式。
- 调整镜像拉取策略:业务允许的前提下,将Pod的
imagePullPolicy从Always修改为IfNotPresent,避免每次创建Pod都触发镜像校验和拉取逻辑,减少冗余引用生成概率。 - 定期清理冗余引用:临时解决可定期执行以下命令清理无关联标签的无名引用,执行前需确认这些引用未被运行中的Pod使用:
ctr -n k8s.io i rm $(ctr -n k8s.io i ls -q | grep '^sha256:' | grep -v '@')
- 规范私有仓库镜像推送:推送镜像到私有仓库时,确保manifest list与对应架构的manifest摘要一致,避免因摘要不匹配触发重复拉取。
内容的提问来源于stack exchange,提问作者mohamed.Yassine.SOUBKI
相关产品推荐
相关产品推荐

