Kubernetes 中的 DNS 查找

笔记。 翻译。:Kubernetes中的DNS问题,或者更准确地说是参数设置问题 ndots,出人意料地受欢迎,而且已经 不是第一个 。 在关于这个主题的另一篇文章中,其作者,一位来自印度一家大型经纪公司的 DevOps 工程师,以非常简单和简洁的方式谈论了对于操作 Kubernetes 的同事来说有用的知识。

Kubernetes 中的 DNS 查找

在 Kubernetes 上部署应用程序的主要好处之一是无缝应用程序发现。 由于服务理念(服务),这是一个支持一组 pod IP 地址的虚拟 IP。 例如,如果服务 vanilla 希望联系服务人员 chocolate,可以直接访问虚拟IP chocolate。 问题出现了:在这种情况下谁将解析 DNS 请求 chocolate 怎么样?

DNS 名称解析是在 Kubernetes 集群上配置的 核心DNS。 Kubelet 使用 CoreDNS 注册一个 pod 作为文件中的名称服务器 /etc/resolv.conf 所有豆荚。 如果你看一下内容 /etc/resolv.conf 任何 pod,它都会看起来像这样:

search hello.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.152.183.10
options ndots:5

DNS 客户端使用此配置将请求转发到 DNS 服务器。 在文件中 resolv.conf 包含以下信息:

  • 名称服务器:DNS 请求将发送到的服务器。 在我们的例子中,这是 CoreDNS 服务的地址;
  • 搜索、:定义特定域的搜索路径。 有趣的是 google.com или mrkaran.dev 不是 FQDN (完全限定域名)。 根据大多数 DNS 解析器遵循的标准约定,只有那些以点“.”结尾(代表根区域)的域才被视为​​完全限定 (FDQN) 域。 有些解析器可以自己添加一个点。 因此, mrkaran.dev. 是完全限定域名 (FQDN),并且 mrkaran.dev - 不;
  • :最有趣的参数(本文就是关于它的)。 ndots 指定请求名称被视为“完全限定”域名之前的阈值点数。 稍后我们分析 DNS 查找序列时会详细讨论这一点。

Kubernetes 中的 DNS 查找

让我们看看当我们询问时会发生什么 mrkaran.dev 在吊舱中:

$ nslookup mrkaran.dev
Server: 10.152.183.10
Address: 10.152.183.10#53

Non-authoritative answer:
Name: mrkaran.dev
Address: 157.230.35.153
Name: mrkaran.dev
Address: 2400:6180:0:d1::519:6001

对于本实验,我将 CoreDNS 日志记录级别设置为 all (这使得它相当冗长)。 我们来看看 pod 的日志 coredns:

[INFO] 10.1.28.1:35998 - 11131 "A IN mrkaran.dev.hello.svc.cluster.local. udp 53 false 512" NXDOMAIN qr,aa,rd 146 0.000263728s
[INFO] 10.1.28.1:34040 - 36853 "A IN mrkaran.dev.svc.cluster.local. udp 47 false 512" NXDOMAIN qr,aa,rd 140 0.000214201s
[INFO] 10.1.28.1:33468 - 29482 "A IN mrkaran.dev.cluster.local. udp 43 false 512" NXDOMAIN qr,aa,rd 136 0.000156107s
[INFO] 10.1.28.1:58471 - 45814 "A IN mrkaran.dev. udp 29 false 512" NOERROR qr,rd,ra 56 0.110263459s
[INFO] 10.1.28.1:54800 - 2463 "AAAA IN mrkaran.dev. udp 29 false 512" NOERROR qr,rd,ra 68 0.145091744s

唷。 这里有两件事引起了您的注意:

  • 请求会经历搜索的所有阶段,直到响应包含代码 NOERROR (DNS 客户端理解它并存储它作为结果)。 NXDOMAIN 表示没有找到给定域名的记录。 因为 mrkaran.dev 不是 FQDN 名称(根据 ndots=5),解析器查看搜索路径并确定请求的顺序;
  • 参赛作品 А и АААА 并行到达。 事实上,一次性请求 /etc/resolv.conf 默认情况下,它们的配置方式是使用 IPv4 和 IPv6 协议执行并行搜索。 您可以通过添加选项来取消此行为 single-request в resolv.conf.

注: glibc 可以配置为按顺序发送这些请求,并且 musl - 不,所以 Alpine 用户应该注意。

使用 ndot 进行实验

让我们多做一些实验 ndots 让我们看看这个参数的行为方式。 这个想法很简单: ndots 确定 DNS 客户端是否将域视为绝对域或相对域。 例如,对于一个简单的 google DNS 客户端,它如何知道该域是否是绝对的? 如果你设置 ndots 等于 1,客户会说:“哦,在 google 没有一个点; 我想我会浏览整个搜索列表。” 然而,如果你问 google.com,后缀列表将被完全忽略,因为请求的名称满足阈值 ndots (至少有一点)。

让我们确定一下:

$ cat /etc/resolv.conf
options ndots:1
$ nslookup mrkaran
Server: 10.152.183.10
Address: 10.152.183.10#53

** server can't find mrkaran: NXDOMAIN

核心 DNS 日志:

[INFO] 10.1.28.1:52495 - 2606 "A IN mrkaran.hello.svc.cluster.local. udp 49 false 512" NXDOMAIN qr,aa,rd 142 0.000524939s
[INFO] 10.1.28.1:59287 - 57522 "A IN mrkaran.svc.cluster.local. udp 43 false 512" NXDOMAIN qr,aa,rd 136 0.000368277s
[INFO] 10.1.28.1:53086 - 4863 "A IN mrkaran.cluster.local. udp 39 false 512" NXDOMAIN qr,aa,rd 132 0.000355344s
[INFO] 10.1.28.1:56863 - 41678 "A IN mrkaran. udp 25 false 512" NXDOMAIN qr,rd,ra 100 0.034629206s

自从在 mrkaran 没有一个点,搜索是在整个后缀列表中进行的。

注:实际中取最大值 ndots 仅限 15 名; Kubernetes 中默认值为 5。

生产中的应用

如果应用程序进行大量外部网络调用,则在活动流量的情况下,DNS 可能会成为瓶颈,因为名称解析会产生许多不必要的查询(在系统找到正确的查询之前)。 应用程序通常不会向域名添加根区域,但这听起来像是一种黑客行为。 也就是说,而不是问 api.twitter.com,你可以“硬编码”它 api.twitter.com. (带点)在应用程序中,这将提示 DNS 客户端直接在绝对域上执行权威查找。

此外,从 Kubernetes 版本 1.14 开始,扩展 dnsConfig и dnsPolicy 获得了稳定的状态。 因此,部署 pod 时,可以减少该值 ndots,比如说,最多 3 个(甚至最多 1 个!)。 因此,节点内的每条消息都必须包含完整的域。 当您必须在性能和便携性之间做出选择时,这是典型的权衡之一。 在我看来,只有当超低延迟对您的应用程序至关重要时,您才应该担心这一点,因为 DNS 结果也在内部缓存。

引用

我第一次了解到这个功能是在 K8s 聚会,于25月XNUMX日举行。 除其他事项外,还就这个问题进行了讨论。

以下是一些进一步探索的链接:

  • 说明,为什么 Kubernetes 中 ndots=5;
  • 好东西 更改 ndots 如何影响应用程序性能;
  • 差异 musl 和 glibc 解析器之间。

注意:我选择不使用 dig 在这篇文章。 dig 自动添加一个点(根区域标识符),使域“完全限定”(FQDN), 没有 首先通过搜索列表运行它。 写过这个 以前的出版物之一。 然而,令人惊讶的是,通常必须为标准行为指定一个单独的标志。

祝 DNS 解析愉快! 回头见!

译者PS

另请阅读我们的博客:

来源: habr.com

添加评论