Kubernetes 部署失败之 ErrImagePull&&ImagePullBackOff

错误的容器镜像/非法的仓库权限解决方案:

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 不正确
  • 镜像不存在(或者是在另一个仓库)
  • Kubernetes 没有权限去拉那个镜像

如果你没有注意到你的镜像 tag 的拼写错误,那么最好就用你本地机器测试一下。

通常我会在本地开发机上,用 docker pull 命令,带上 完全相同的镜像 tag,来跑一下。比如上面的情况,我会运行命令 docker pull prod-nexus/myapp:v1.0

  • 如果这成功了,那么很可能 Kubernetes 没有权限去拉取这个镜像。参考镜像拉取 Secrets 来解决这个问题。
  • 如果失败了,那么我会继续用不显式带 tag 的镜像测试 - docker pull prod-nexus/myapp - 这会尝试拉取 tag 为 latest 的镜像。如果这样成功,表明原来指定的 tag 不存在。这可能是人为原因,拼写错误,或者 CI/CD 的配置错误。


如果 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

如有其它高见,欢迎留言补充!

你可能感兴趣的:(docker,kubernetes,个人感想)