kubectl get pods 状态为ErrImagePull && ImagePullBackOff (一直在restarting)
当我们创建一个名字为myapp的deployment的时候,它指向的是一个不存在的docker镜像:
最常见的有两个问题:
(a)指定了错误的容器镜像
(b)使用私有镜像却不提供仓库认证信息
$ kubectl run myapp --image=prod-nexus/myapp:v1.0
然后我们查看 Pods,可以看到有一个状态为 ErrImagePull 或者 ImagePullBackOff 的 Pod:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-102132443982-dsafx 0/1 ImagePullBackOff 0 3m
想查看更多信息,可以 describe 这个失败的 Pod:
$ kubectl describe pod myapp-102132443982-dsafx
显示错误的那句话:Failed to pull image "prod-nexus/myapp:v1.0": Error: image prod-nexus/myapp not found 告诉我们 Kubernetes无法找到镜像 prod-nexus/myapp:v1.0。
因此问题变成:为什么 Kubernetes 拉不下来镜像?
除了网络连接问题外,还有三个主要元凶:
如果你没有注意到你的镜像 tag 的拼写错误,那么最好就用你本地机器测试一下。
通常我会在本地开发机上,用 docker pull 命令,带上 完全相同的镜像 tag,来跑一下。比如上面的情况,我会运行命令 docker pull prod-nexus/myapp:v1.0。
如果 docker pull prod-nexus/myapp(不指定 tag)也失败了,那么我们碰到了一个更大的问题:我们所有的镜像仓库中都没有这个镜像。默认情况下,Kubernetes 使用 Dockerhub 镜像仓库,如果你在使用 Quay.io,AWS ECR,或者 Google Container Registry,你要在镜像地址中指定这个仓库的 URL,比如使用 Quay,镜像地址就变成 prod-nexus/myapp:v1.0。
如果你在使用 Dockerhub,那你应该再次确认你发布镜像到 Dockerhub 的系统,确保名字和 tag 匹配你的 deployment 正在使用的镜像。
注意:观察 Pod 状态的时候,镜像缺失和仓库权限不正确是没法区分的。其它情况下,Kubernetes 将报告一个 ErrImagePull 状态。
####################################################################################################
在此之上,你都没解决的话,还有个致命的坑:
日志中类似的错误如下:kubectl describe pod 你的deployment 中的pod名
Jun 12 17:02:06 k8s kubelet[1345]: E0612 17:02:06.942588 1345 docker_manager.go:2295] container start failed: ImagePullBackOff: Back-off pulling image “reg.docker.lc/share/nginx:latest”
Jun 12 17:02:06 k8s kubelet[1345]: E0612 17:02:06.942643 1345 pod_workers.go:184] Error syncing pod cb61d30a-4f4d-11e7-8ea8-000c29e9277a, skipping: failed to “StartContainer” for “nginx” with ImagePullBackOff: “Back-off pulling image \”reg.docker.lc/share/nginx:latest\””
主要问题还是在于yaml配置文件的写法问题。
具体的参数:imagePullPolicy: Always (这是默认的参数)即
镜像的拉取策略:总是拉取。由于我的yaml中没有添加这个选项,所以就默认设置为always,也就是说他会默认自动去远程拉取镜像,并不使用本地的镜像。
详见参数可选项见官方文档:https://kubernetes.io/docs/concepts/containers/images/
默认情况是会根据配置文件中的镜像地址去拉取镜像,如果设置为IfNotPresent 和Never就会使用本地镜像。
IfNotPresent :如果本地存在镜像就优先使用本地镜像。
Never:直接不再去拉取镜像了,使用本地的;如果本地不存在就报异常了。
参数的具体用法:
spec:
containers:
- name: nginx
image: image: reg.docker.lc/share/nginx:latest
imagePullPolicy: IfNotPresent #或者使用Never
因为此参数默认为:imagePullPolicy: Always
,如果你yaml配置文件中没有定义那就是使用默认的。
更改完之后,再次利用kubectl启动一个deployment,就可以创建成功了。
补充1:https://blog.csdn.net/u013641234/article/details/103481464