配置kubernetes从注册表服务中提取

时间:2018-04-06 18:34:14

标签: docker kubernetes kube-dns

所以,我试图让我的kube集群从内部运行的注册表中拉出来。我有kube dns设置,我有一个注册表部署和服务运行。我可以通过节点上的host命令解析服务内部名称。我在docker守护进程中添加了--dns标志,其中包含kube dns服务的地址。我的kubelet运行时--cluster-dns标志也设置为相同的地址。然而,当我尝试使用此注册表创建一个pod时,这就是我得到的。

Failed to pull image "kube-registry.kube-system.svc.cluster.local/myuser/myimage": rpc error: code = Unknown desc = Error response from daemon: Get https://kube-registry.kube-system.svc.cluster.local/v1/_ping: dial tcp: lookup kube-registry.kube-system.svc.cluster.local: no such host

不知何故,即使将kube dns地址明确地提供给dockerd和kubelet,由于名称解析,从注册表服务中提取图像也会失败。我错过了什么?

2 个答案:

答案 0 :(得分:1)

问题:“我正在尝试从内部运行的注册表中拉取我的 kube-cluster。” (请注意,我打算编辑您的问题标题以稍微澄清/使其更易于搜索)

简短回答:你不能*
*细致入微的回答:从技术上讲,通过黑客攻击和对 Kubernetes 基础知识的深入了解是可能的。您可能希望避免这样做,除非您有很好的理由,并且完全理解我对基本问题和解决方法的解释,因为这是一个高级用例,需要调试才能使其工作。这很复杂且细微到足以使逐步指导变得困难,但我可以让您对您遇到的基本问题有一个可靠的了解,这些问题使这个具有挑战性,以及有关如何完成您正在尝试的工作的高级概述指南无论如何。

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

  • 互联网 DNS:8.8.8.8、1.1.1.1、9.9.9.9(google、cloudflare、quad9 或路由器配置指向的任何公共互联网 DNS。)
  • LAN DNS:192.168.1.1(在您的路由器上托管的 LAN DNS)
  • CoreDNS:10.43.0.10(内部集群网络 CIDR 范围的第 10 个 IP)

这是您遇到的问题:

  • Pod 可以解析托管在这 3 个 DNS 级别中的任何一个级别的 DNS 条目。
  • 托管 Kubernetes 集群的操作系统只能解析托管在 LAN DNS 或 Internet DNS 上的 DNS 条目。 (操作系统的范围不包括 CoreDNS/内部集群网络的存在。)
  • kubelet + docker/containerd/cri-o/other 运行时,负责从注册表中提取镜像,这些镜像以 systemd 服务的形式存在于操作系统级别,因此没有内部集群 DNS 名称的范围。这就是您尝试做的事情失败的原因。

您可以采取的解决方法选项/技巧和细微差别,以强制您尝试执行的操作:

选项 1。)(我不建议这样做,有额外困难的鸡和蛋问题,仅供参考)

托管一个额外的 coredns 实例作为面向 LAN 的实例 Kubernetes 上的 DNS,将注册中心和第二个 coredns 实例暴露给 LAN 通过显式 NodePorts(使用静态服务清单,因此 他们会提出可预测的/静态的 NodePorts,而不是随机的 NodePorts 在 30000 - 32768 范围内)所以它们可以从 LAN(我建议在这里使用 LB 上的 NodePorts 作为一种更少的依赖/事物 这可能会出错)。让 coredns 的第二个实例使用您的 LAN 路由器/局域网 DNS,因为它是上游 DNS 服务器。重新配置操作系统以使用 面向 coredns 的 LAN,因为它是 DNS 服务器。

选项 2.) 更合理以及 trow 的作用:

  1. 支付 12 美元购买 some-dns-name.tld

  2. 使用 Cert Manager Kubernetes Operator 或 Cert Bot 独立 docker 容器 + 证明您拥有域,以从 Lets Encrypt Free 获取 https://registry.some-dns-name.tld HTTPS 证书。并配置您的内部集群托管注册表以使用此 HTTPS 证书。

  3. 使用 NodePort 服务将集群中托管的注册表暴露给 LAN,该服务具有基于明确固定的约定的端口号,例如 32443

<块引用>

为什么是 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.) 如果您需要更改集群的托管位置,您可以 可以安排它,以便您可以在 1 个集中位置进行更改 即使在您无法访问或控制 LAN DNS 的情况下。 您可以制作指向静态定义的 IP 或外部的服务 名称(可能存在于集群之外)。并拥有 NodePort 服务指向静态定义的服务。

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

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

  3. 还有两个可解决的鸡和蛋问题需要处理。第一个鸡蛋问题是 Kubernetes 和注册中心都可能需要访问容器镜像才能做到这一点。

  • 如果您可以访问互联网并且您的内部注册表仅用于缓存目的,这可能没什么大不了的。
  • 如果您无法访问互联网,则需要将 kube 发行版和注册表所需的图像压缩为 .tar,并将它们“预加载”到 docker/containerd/cri-o 期望的位置。
  • 如果您无法访问互联网,您也可以拥有另一个 /etc/hosts 条目或 LAN DNS 条目,用于非 HA 临时基于 docker compose 的注册表,用于初始引导或托管在集群外部。
  1. 第二个鸡蛋问题是托管在您的集群上的注册表需要某种方式来植入图像。
  • 如果互联网访问应该很容易弄清楚并编写脚本
  • 如果无法访问互联网,您可能需要想出某种灾难恢复解决方案来备份和恢复注册表后端持久存储。
  • 如果无法访问互联网,您也可以使用“临时传输注册表”进行播种。基本上做这个 docker compose 以使用文件系统支持启动非 HA 注册表:2 映像,使用 skopeo 进行播种,将文件系统支持压缩,然后将其导入另一台计算机,恢复文件系统支持,重新加载非-HA 注册表:2 来自预填充的文件系统支持,然后使用 skopeo 从您的“临时传输注册表”复制到集群中托管的注册表。

答案 1 :(得分:0)

另一种解决方案是将kube-dns IP添加到resolv.conf

echo "nameserver $(kubectl -n kube-system get svc kube-dns -o jsonpath='{.spec.clusterIP}')" >> /etc/resolv.conf

CoreDNS服务以static IP公开,因此无需保持更新。

我可以确认它可以在Ubunutu 18.04上运行,尽管resolv.conf是由systemd-resolved生成的。不需要其他DNS配置。仅FQDN提供的服务:

root@dev:~# nslookup harbor.default.svc.cluster.local
;; Got SERVFAIL reply from 127.0.0.53, trying next server
Server:     10.96.0.10
Address:    10.96.0.10#53

Name:   harbor.default.svc.cluster.local
Address: 10.109.118.191
;; Got SERVFAIL reply from 127.0.0.53, trying next server