当前位置: 首页 > 知识库问答 >
问题:

如何配置kubernetes以从驻留在同一集群中/自身内部的注册表中提取容器映像

钱睿范
2023-03-14

我试图让我的kubernetes集群从内部运行的容器注册服务中拉出。我有库贝dns设置,我有一个注册表部署和服务运行。我可以通过节点上的主机命令解析服务内部名称。我已经用kube dns服务的地址向docker守护进程添加了--dns标志。我在运行kubelet时也将--cluster-dns标志设置为相同的地址。然而,当我尝试使用这个注册表创建一个pod时,不知何故,这就是我得到的结果。

无法拉出映像“kube-registry.kube-system.svc.cluster.local/myuser/myimage”:rpc错误:code=未知desc=后台程序的错误响应:Get https://kube-registry.kube-system.svc.cluster.local/v1/_ping:dial tcp:lookup kube-registry.kube-system.svc.cluster.local:没有这样的主机

不知何故,即使将kube dns地址显式地提供给dockerd和kubelet,从注册表服务提取映像也会因为名称解析而失败。我错过了什么?

共有1个答案

丁翰海
2023-03-14

问题:“我正在尝试让我的kube-cluster从运行在自己内部的注册表中拉出。”(注意:我打算编辑你问题的标题,稍微澄清一下/使搜索更容易)

简短的回答:你不能*
*细致入微的回答:从技术上来说,通过黑客和对Kubernetes基本原理的扎实理解,这是可能的。您可能希望避免这样做,除非您有一个非常好的理由,并且完全理解我对基本问题和解决方案的解释,因为这是一个高级用例,需要调试才能使其工作。这是复杂和微妙的,足以使一步一步的指导变得困难,但我可以给你一个坚实的想法,你遇到的基本问题,使这一挑战,并对如何完成你试图做的事情提供高层次的概述指导。

为什么不能/您遇到的基本问题:
在Kubernetes land中,通常存在3个网络:Internet、LAN和内部集群网络。
(更深入的参考资料:https://oteemo.com/kubernetes-networking-and-services-101/)
这3个网络都有自己的DNS/有3个DNS层。

  • internet DNS:8.8.8.8、1.1.1.1、9.9.9.9(google、cloudflare、quad9或路由器配置为指向的任何公共internet DNS。)
  • LAN DNS:192.168.1.1(路由器上承载的LAN DNS)
  • 核心:10.43.0.10(内部群集网络CIDR范围的第10个IP)

以下是你遇到的问题:

  • 吊舱可以解析驻留在以下3个DNS级别中任一级别的DNS项。
  • 承载Kubernetes群集的操作系统只能解析LAN DNS或Internet DNS上承载的DNS条目。(操作系统的范围不是要对CoredNs/内部集群网络的存在具有可见性。)
  • kubelet+docker/containerd/cri-o/other runtime负责从注册表中提取映像,这些映像以systemd服务的形式存在于OS级别,因此不具有内部集群DNS名称的作用域。这就是为什么您试图做的事情失败了。

备选案文2.)更合理和trow的工作:

>

  • 什么是trow:https://thenewstack.io/trow-a-container-registry-to-run-inside-a-kubernetes-cluster/

    证明他们使用/etc/hosts方法https://github.com/containersolutions/trow/blob/main/quick-install.md

    为什么是NodePort而不是LB?在这种情况下,NP比LB更好有3个原因:

    >

  • 1.)服务类型LB的实现在部署环境和Kubernetes发行版之间有所不同,而类型NodePort则是通用的。

    2.)如果LB发生了变化,您必须更新每个节点的/etc/host文件,使其指向“lb_ip registry.some-dns-name.tld”,并且您必须知道LB IP,这并不总是事先知道的/这意味着您必须遵循某种操作顺序。如果使用服务类型NodePort,您可以将localhost IP条目添加到每个节点的/etc/host中,因此它看起来像“127.0.0.1 registry.some-dns-name.tld”,这是众所周知的可重用性,并简化了操作顺序。

    3.)如果您需要更改群集的宿主位置,您可以进行安排,以便即使在无法访问或控制LAN DNS的情况下也可以在1个集中位置进行更改。您可以创建指向静态定义的IP或外部名称(可能存在于群集之外)的服务。并使NodePort服务指向静态定义的服务。

    将“127.0.0.1 registry.some-dns-name.tld”添加到集群中每个节点的/etc/hosts中。

    将yaml清单设置为从registry.some-dns-name.tls中提取,或者配置containerd/cri-o的注册表镜像功能,将registry.some-dns-name.tld:32443映射到本地注册表中镜像的任何条目。

    还有两个可解决的鸡和蛋的问题要处理。第一个问题是Kubernetes和registry可能都需要访问容器图像才能做到这一点。

    • 如果您可以访问internet并且内部注册表只是用于缓存,这可能没什么大不了的。
    • 如果您没有互联网接入,您需要。将kube dustro和注册表所需的图像焦油化,并将它们“预加载”到spot Docker/containerd/cri-o expected中。
    • 如果您没有internet访问权限,您也可以为用于初始引导的非HA临时docker compose注册表或驻留在群集之外的注册表设置另一个/etc/hosts条目或LAN DNS条目。
    • 如果internet访问应该容易理解和编写脚本
    • 如果没有internet访问,您可能需要想出某种DR解决方案来备份和恢复注册表后端持久存储。
    • 如果没有internet访问,您也可以使用“强调传输注册表”作为种子目的。基本上,使用这个docker compose来旋转带有文件系统支持的非HA注册表:2映像,使用skopeo来种子该映像,将文件系统支持添加到焦油中,并将其导入到另一台计算机中,还原文件系统支持,从预先填充的文件系统支持中重新加载非HA注册表:2,然后使用skopeo从您的“临时传输注册表”复制到集群中托管的注册表。

  •  类似资料:
    • 我有一个Kubernetes的工作实例: 如何编写图像名称,使其始终从我自己的命名空间中提取。 我想这样设置: 但它没有说它无法提取图像

    • 我在Linode上有一个K8s集群和另一个用于操作的VM。 我已经安装了Docker 注意:我还没有在这个虚拟机上安装迷你库贝。 我可以构建我的映像,但无法将其从本地注册表拉到k8s pod。 以下是我已经做过的事情 创建docker镜像并将其推送到本地注册表 从图像中运行docker容器,但不会在K8s中被拉入 创建“regcred”secret并在部署yaml中使用它 创建映像并使用VM的IP

    • 问题内容: 我已经建立了一个4节点kubernetes集群,该集群运行都在CoreOS上运行的多容器Pod。这些图像来自公共和私人存储库。现在,我必须登录到每个节点,并在每次更新图像时手动下拉图像。我希望能够自动将其拉出。 我试过在每台服务器上运行docker登录并将.dockercfg文件放在/ root和/ core中 我也使用.docker / config.json完成了上述操作 我已将密

    • 问题内容: 一个的类上堆和参考变量指向它创建。 如果我写的时候没看错 类的对象在堆上创建并指向它。在堆中,我们有两个单独的对象,其中包含它们自己的实例变量。 但是如果我写 还有两个将在堆上创建,一个用于,另一个用于。但仅提供参考 即可。谁指的是堆外层?如果没有任何引用引用它,那么它应该有资格进行垃圾回收,这将影响的使用。 问题答案: 内部类包含对其外部类实例的隐藏引用。如果没有其他引用,则该隐藏引

    • 问题内容: 我对Google Cloud平台和Docker相当陌生,并设置了一个节点集群,制作了一个Dockerfile,该文件可复制存储库并在公共端口上运行Clojure REPL。我可以从IDE连接到它,然后播放我的代码,太棒了! 但是该REPL应该应该通过SSH进行隧道传输,但这是我的问题开始的地方。 我找不到合适的SSH位置来 更改Docker在其上运行REPL的存储库: 公开的IP仅公开

    • 我正在使用一个安装了docker的docker映像,为了运行任务来清理我的kubernetes集群中每个节点上的docker映像数据。我尝试使用Daemonset,因为它将在除master之外的每个节点上运行,但是在docker容器中运行cron被证明是徒劳的。 因此,我尝试使用K8s Cronjob,它定期运行,具有以下属性: 和 我正在运行一个 shell 脚本,该脚本从上述 CronJob