Kubernetes中的DNS查找

注意佩雷夫。:Kubernetes中的DNS问题(或更确切地说是参数设置ndots)出人意料地流行,而且这不是第一 。在有关此主题的另一篇文章中,其作者,印度一家大型经纪公司的DevOps工程师以非常简单和简洁的方式讲述了了解使用Kubernetes的同事的有用之处。



在Kubernetes中部署应用程序的主要优势之一是无缝发现应用程序。服务概念( Service)是一个虚拟IP,它支持设置的pod'ov IP地址,从而大大简化了集群内部的交互。例如,如果服务vanilla要联系该服务chocolate,则可以直接访问该虚拟IPchocolate问题出现了:在这种情况下,谁将解析DNS查询到谁,chocolate以及如何解决

DNS名称解析是使用CoreDNS在Kubernetes集群中配置的Kubelet在/etc/resolv.conf所有Pod 的文件中将Pod以CoreDNS注册为名称服务器如果您查看/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包含以下信息:

  • nameserver:DNS查询将被路由到的服务器。在我们的例子中,这是CoreDNS服务的地址;
  • search: . , google.com mrkaran.dev FQDN ( ). , resolver' DNS, (FDQN) , «.», . resolver' . , mrkaran.dev. — (FQDN), mrkaran.dev — ;
  • ndots: ( ). ndots , «» . , DNS-.



让我们看看mrkaran.dev在pod中请求时会发生什么

$ 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

FUH。这里有两件事引起注意:

  • 该请求将遍历搜索的所有阶段,直到响应包含代码NOERROR(DNS客户端会理解该代码并将其存储为结果)。NXDOMAIN表示找不到该域名的记录。由于mrkaran.dev它不是FQDN名称(根据ndots=5),因此解析程序会查看搜索路径并确定查询的顺序;
  • . , /etc/resolv.conf , IPv4 IPv6. , single-request resolv.conf.

: glibc , musl — , Alpine .

ndots


让我们进行更多实验,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

CoreDNS日志:

[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可能会成为活动流量的瓶颈,因为解析名称时,会执行许多不必要的查询(在系统找到正确的查询之前)。应用程序通常不会在域名中添加根区域,但这确实是一个hack。也就是说api.twitter.com,您可以api.twitter.com.在应用程序中(用点)对代码进行硬编码而不是询问),这将提示DNS客户端立即在绝对域中执行权威性搜索。

此外,从Kubernetes 1.14版本开始,扩展dnsConfigdnsPolicy获得了稳定状态。因此,在部署Pod时,您可以降低价值ndots,例如,最多3个(甚至最多1个!)。因此,节点内的每个消息都必须包含完整的域。当您必须在性能和便携性之间进行选择时,这是经典的折衷方案之一。在我看来,仅当超低延迟对您的应用程序至关重要时,才有必要担心此问题,因为DNS结果也在内部缓存。

参考文献


我第一次在1月25日K8s会议了解了此功能在那里进行了讨论,包括有关此问题的讨论。

以下是一些进一步研究的链接:

  • 解释为什么Kubernetes中的ndots = 5;
  • 伟大的东西如何改变的ndots影响应用程序的性能;
  • 分辨肌和glibc之间的差异

注意:我选择不使用dig本文。dig自动添加一个点(根区域标识符),使域“满”(FQDN),而无需先在搜索列表中运行它。在以前的出版物之一中对此作了论述但是,令人惊讶的是,通常必须为标准行为设置一个标准标志。

良好的DNSing!回头见!

译者的PS


另请参阅我们的博客:


All Articles