【问题标题】:How to use local docker images in kubernetes deployments (NOT minikube)如何在 kubernetes 部署中使用本地 docker 镜像(不是 minikube)
【发布时间】:2021-12-27 02:24:13
【问题描述】:

我有一个使用 kubeadm(不是 minikube)安装了 kubernetes 的 VM。 VM 充当集群的单个节点,移除了污点以允许它充当主节点和工作节点(如 kubernetes 文档中所示)。 我已将我的 app:test 图像保存、传输并加载到其中。我可以使用 docker run 轻松运行容器。 它在我运行 sudo docker images 时出现。

当我创建使用此映像的部署/pod 并指定 Image-PullPolicy: IfNotPresentNever 时,我仍然有 ImagePullBackoff错误。 describe 命令显示它试图从 dockerhub 中提取图像...

请注意,当我尝试使用 由于创建另一个 pod 而被拉取的本地图像时,ImagePullPolicies 似乎可以正常工作,没问题。虽然当我运行 sudo docker images --all 时没有出现 图像。

如何在 Kubernetes 中为 pod 使用本地映像?有没有办法在不使用私有存储库的情况下做到这一点?

【问题讨论】:

  • 你用的是哪个kubernetes版本?
  • 我使用的是v1.22版本

标签: kubernetes containers cloud orchestration


【解决方案1】:

当我运行 sudo docker images --all 时,图像没有出现

根据您的评论,您使用的是 K8s v1.22,这意味着您的集群很可能正在使用 containerd 容器运行时而不是 docker(您可以使用 kubectl get nodes -o wide 检查,并查看最后一列) .

尝试使用crictl images 列出您的图像并使用crictl pull <image_name> 拉取以将图像预加载到节点上。

【讨论】:

  • 我会试试的。不是docker use containerd as the runtime under the hood吗?这就是我使用 containerd 作为节点的原因;这样我就可以依靠 docker 来获取有关我的图像的信息。我错了吗?
  • 这是正确的,docker 确实使用了containerd 本身,只是k8s 不再使用docker 作为中间人了。使用crictl 查看您是否可以进一步了解。您可以在我的一个 k8s 节点here 上查看dockercontainerd 列出图像的示例。
  • 谢谢。运行 crictl images,我的图像确实没有弹出。但是,当我尝试拉取它时,我收到以下错误消息:FATA[0000] pull image failed: rpc error: code = Unknown desc = failed to pull and unpack image "docker.io/library/app:test": failed to解决参考“docker.io/library/app:test”:拉取访问被拒绝,存储库不存在或可能需要授权:服务器消息:不足_范围:授权失败
  • 使用 crictl 不起作用,但跟随 these steps 工作正常...知道为什么 crictl 可能无法拉动吗?
  • 这似乎是一个私人仓库?
【解决方案2】:

如果使用 containerd,可以结合使用 crictl 和 ctr。

TLDR: these steps,在crictl github documentation中也有描述:

1- 在节点(在我的例子中是 VM)上获取映像后,请确保它位于存档 (.tar) 中。您可以使用docker savectr image export 命令来做到这一点。

2- 在存档镜像所在的同一目录中使用sudo ctr -n=k8s.io images import myimage.tar 将其添加到 kubernetes 用来跟踪其镜像的命名空间中的 containerd。现在,它应该会在您运行 sudo crictl images 时出现。


按照建议,我尝试使用 crictl 列出图像,但我的 app:test 没有出现。但是,尝试通过 crictl 导入我的本地图像似乎也不起作用。我使用 crictl pull app:test 并显示以下错误消息:

FATA[0000] 拉取镜像失败:rpc 错误:代码 = 未知 desc = 无法拉取和解压镜像“docker.io/library/app:test”:无法解析参考“docker.io/library/app:测试”:拉取访问被拒绝,存储库不存在或可能需要授权:服务器消息:不足的范围:授权失败。

但是,当关注these steps时,我的图像最终被识别为kubernetes中现有的本地图像。它们实际上与crictl中建议的相同github documentation

如何解释这一点?镜像如何在 Kubernetes 集群中“注册”?为什么 crictl 不能导入图像?我可能会发布另一个问题来问...

【讨论】:

  • 由于外部链接趋于消失,最好总结一下这个答案中的“这些步骤”到底是什么。
  • 已记录,正在编辑。
【解决方案3】:

您的集群被装瓶在您的虚拟机中,因此对于该虚拟机中的该集群,您所谓的本地将始终是远程的。而 Kubernetes 之所以试图拉取这些镜像,是因为它在 VM 中找不到它们。

Dockerhub 是下载容器的默认位置,但您可以将 kubernetes 设置为从 aws (ECR)、azure (ACR)、github 包 (GCR) 和您自己的私有服务器中提取。

你有大约 100 种方法来解决这个问题,但没有一种是简单的,也不会奏效的。

1 - 最简单,将您的图像推送到 Dockerhub 并让您的集群从中提取。

2 - 设置本地私有容器注册表并设置您的 Kubernetes 虚拟机以从中提取 (see this)

3 - 在您的 kubernetes 集群中设置一个私有容器注册表,并在您的本地环境中设置脚本以推送到它(see this)

【讨论】:

  • “瓶装”到底是什么意思?我确实将图像放在了虚拟机上......这是我困惑的根源。其他由 Kubernetes 拉取的镜像可以被重用,即使它们没有出现在虚拟机上。怎么样?
  • 在封装的意义上装瓶,你的虚拟机无权访问你的机器,你的机器也无权访问你的虚拟机,除非你使用 ssh 或挂载文件夹访问它,但仅此而已联网。从某种意义上说,你的虚拟机看不到你机器的图像,反之亦然。
  • 当您的意思是“出现在 VM 上”时,您是指运行“docker image ls”吗?如果是这样,那可能是因为 kubernetes 使用了不同的容器驱动程序。 Docker 只是与容器交互的一种方式,它是最著名和最真实的硬核容器 linux 人们讨厌 docker,因为 docker 是一家公司,它有自己的议程。我认为 kubernetes 现在正在使用 CRI-O 作为默认容器运行时,尝试运行 crictl images 以查看 kubernetes 拉取的图像
  • 好的,在这种情况下我不得不说:这不是问题所在。正如我的问题中所述,我确实将图像传输到我的虚拟机上并将其加载到那里。运行 docker images 在虚拟机上显示它。是的,这就是我的意思。我在设置 kubernetes 时,关注的是instructions to use containerd as a runtime。 Docker 也使用 containerd,所以 docker 镜像应该是相关的,不是吗?
  • 知道了,是的,kubernetes 使用的映像都应该显示在您的 VM 上,愚蠢的问题,您是使用带有映像版本的完整标签还是仅使用映像名称?您可以使用部署或 pod 规范更新您的问题吗?让我们深入了解这一点
猜你喜欢
  • 2017-07-22
  • 2019-11-26
  • 2015-08-04
  • 1970-01-01
  • 2020-01-06
  • 2019-11-25
  • 1970-01-01
  • 2018-02-14
  • 2019-03-29
相关资源
最近更新 更多