Kubernetes无法拉取本地构建镜像问题求助
我正在使用Kubernetes 1.26版本,拥有一个单节点集群,该节点同时作为master和worker节点。我已在本地构建了一个Docker镜像,可通过docker images命令查看:
$ sudo docker images | grep nipun nipun/a 1.0 ed1059539edf 52 minutes ago 250MB
但当我在Deployment中使用该镜像nipun/a:1.0,并设置imagePullPolicy为Never或IfNotPresent时,Kubernetes仍尝试拉取镜像并失败。我的Deployment定义如下:
apiVersion: apps/v1 kind: Deployment metadata: name: nipun-deployment labels: app: nipun spec: replicas: 1 selector: matchLabels: app: nipun template: metadata: labels: app: nipun spec: containers: - name: nipun image: nipun/a:1.0 imagePullPolicy: Never ports: - containerPort: 8112
我在较低版本的K8s(大概1.20)中使用相同方法是有效的,请问可能的问题是什么?
1. 容器运行时切换导致镜像不互通
Kubernetes 1.24及以后版本默认不再以Docker作为容器运行时,转而使用containerd。如果你的1.26集群是默认部署,节点使用的是containerd而非Docker,那么你在Docker中构建的镜像不会被containerd识别,K8s自然找不到本地镜像而尝试拉取。
解决方法:
将Docker镜像导入到containerd中:
# 保存Docker镜像为tar包 sudo docker save -o nipun-a-1.0.tar nipun/a:1.0 # 导入到containerd sudo ctr images import nipun-a-1.0.tar # 验证导入结果 sudo ctr images list | grep nipun
2. 镜像拉取策略的缓存冲突
如果之前该Deployment使用过其他镜像标签,或者Pod配置存在缓存,可能导致新设置的imagePullPolicy未生效。
解决方法:
删除现有Deployment并重新创建,确保配置完全生效:
kubectl delete deployment nipun-deployment kubectl apply -f your-deployment.yaml
3. 镜像命名不符合containerd规范
containerd对本地镜像的命名有更严格的OCI规范要求,不带仓库前缀的镜像名称(如nipun/a:1.0)可能无法被正确识别。
解决方法:
给镜像添加localhost前缀后重新导入:
# 重新打标签 sudo docker tag nipun/a:1.0 localhost/nipun/a:1.0 # 保存并导入到containerd sudo docker save -o nipun-a-local.tar localhost/nipun/a:1.0 sudo ctr images import nipun-a-local.tar
然后修改Deployment中的镜像字段为localhost/nipun/a:1.0,保持imagePullPolicy: Never。
4. 单节点master的污点限制
默认情况下,master节点带有node-role.kubernetes.io/control-plane:NoSchedule污点,如果Pod没有对应的容忍度,可能出现调度异常(虽然单节点下调度会强制执行,但部分场景下可能引发镜像拉取的间接问题)。
解决方法:
在Deployment的Pod模板中添加容忍度:
spec: tolerations: - key: "node-role.kubernetes.io/control-plane" operator: "Exists" effect: "NoSchedule" containers: # 原有容器配置...
内容的提问来源于stack exchange,提问作者Nipun Talukdar

