前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes 中的 DNS 查询

Kubernetes 中的 DNS 查询

作者头像
我是阳明
发布2020-06-15 18:14:25
5.3K0
发布2020-06-15 18:14:25
举报
文章被收录于专栏:k8s技术圈k8s技术圈

原文地址:https://mrkaran.dev/posts/ndots-kubernetes/

在 Kubernetes 中部署应用的主要优势之一就是可以做到无缝的应用发现。Service 的概念使群集内通信变得容易,Service 代表了支持一组 Pod IP 的虚拟 IP。在 Kubernetes 内部可以直接通过 Service 来访问服务,现在的问题是谁解决了服务的 DNS 查询问题?

DNS 解析是通过 Kubernetes 集群中配置的 CoreDNS 完成的,kubelet 将每个 Pod 的 /etc/resolv.conf 配置为使用 coredns pod 作为 nameserver。我们可以在任何 Pod 中看到 /etc/resolv.conf 的内容,如下所示:

代码语言:javascript
复制
search hello.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.152.183.10
options ndots:5

DNS 客户端使用此配置将 DNS 查询转发到 DNS 服务器, resolv.conf 是解析程序的配置文件,其中包含以下信息:

  • nameserver:DNS 查询转发到的服务地址,实际上就是 CoreDNS 服务的地址。
  • search:表示特定域的搜索路径,有趣的是 google.com 或 mrkaran.dev 不是 FQDN 形式的域名。大多数 DNS 解析器遵循的标准约定是,如果域名以 . 结尾(代表根区域),该域就会被认为是 FQDN。有一些 DNS 解析器会尝试用一些自动的方式将 . 附加上。所以, mrkaran.dev. 是 FQDN,但 mrkaran.dev 不是。
  • ndots:这是最有趣的一个参数,也是这篇文章的重点, ndots 代表查询名称中的点数阈值,Kubernetes 中默认为5,如果查询的域名包含的点 “.” 不到5个,那么进行 DNS 查找,将使用非完全限定名称,如果你查询的域名包含点数大于等于5,那么 DNS 查询默认会使用绝对域名进行查询。

ndots 点数少于 5个,先走 search 域,最后将其视为绝对域名进行查询;点数大于等于5个,直接视为绝对域名进行查找,只有当查询不到的时候,才继续走 search 域。

FQDN 维基解释:完全限定域名(英语:Fully qualified domain name),缩写为 FQDN,又译为完全资格域名、完整领域名称,又称为绝对领域名称(absolute domain name)、 绝对域名,域名的一种,能指定其在域名系统 (DNS) 树状图下的一个确实位置。一个完全资格域名会包含所有域名级别,包括 顶级域名 和 根域名。完整域名由主机名称与母域名两部分所组成,例如有一部服务器的本地主机名为 myhost,而其母域名为 example.com,那指向该服务器的完整域名就是 myhost.example.com。虽然世界上可能有很多服务器的本地主机名是 myhost,但 myhost.example.com 是唯一的,因此完整域名能识别该特定服务器。

我们来检查一下在 Pod 中查询 mrkaran.dev 时会发生什么:

代码语言:javascript
复制
$ 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,这样我们看到具体的解析过程,让我们看一下 coredns pod 的日志:

代码语言:javascript
复制
[INFO] 10.1.28.1:35998- 11131"A IN mrkaran.dev.hello.svc.cluster.local. udp 53 false 512" NXDOMAIN qr,aa,rd 1460.000263728s
[INFO] 10.1.28.1:34040- 36853"A IN mrkaran.dev.svc.cluster.local. udp 47 false 512" NXDOMAIN qr,aa,rd 1400.000214201s
[INFO] 10.1.28.1:33468- 29482"A IN mrkaran.dev.cluster.local. udp 43 false 512" NXDOMAIN qr,aa,rd 1360.000156107s
[INFO] 10.1.28.1:58471- 45814"A IN mrkaran.dev. udp 29 false 512" NOERROR qr,rd,ra 560.110263459s
[INFO] 10.1.28.1:54800- 2463"AAAA IN mrkaran.dev. udp 29 false 512" NOERROR qr,rd,ra 680.145091744s

上面日志中有两条信息值得我们注意:

  • 该查询将遍历所有搜索路径,直到响应中包含 NOERROR 信息, NXDOMAIN 表示未找到该域名的记录。由于 mrkaran.dev 不是 FQDN,根据 ndots=5 设置,因此解析程序会先查看 search 路径。
  • AAAAA记录会并行触发,这是因为 /etc/resolv.conf 中的 single-request 选项具有默认配置来并行执行 IPv4 和 IPv6 查找,我们也可以使用 single-request 选项来禁用该功能。

注意:可以将 glibc 配置为按顺序发送这些请求,但是 musl 无法发送,所以 Alpine 用户必须要注意这点。

接下来让我们测试一下改变 ndots 之后的变化。通过 ndots 设置,DNS 客户端可以知道一个域名是否是绝对的。例如,如果您仅查询 google,DNS 客户端会知道这不是一个绝对域,如果您将 ndots 设置为1,DNS 客户端会说:”哦,google 连一个点都没有,我们来尝试遍历搜索列表查找下“。但是,如果您查询 google.com,则搜索列表将会被完全忽略,因为查询的名称满足 ndots 阈值(至少一个点),查询不到的时候才会去搜索列表进行查询。

我们可以通过实际操作看到它:

代码语言:javascript
复制
$ 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 日志如下所示:

代码语言:javascript
复制
[INFO] 10.1.28.1:52495- 2606"A IN mrkaran.hello.svc.cluster.local. udp 49 false 512" NXDOMAIN qr,aa,rd 1420.000524939s
[INFO] 10.1.28.1:59287- 57522"A IN mrkaran.svc.cluster.local. udp 43 false 512" NXDOMAIN qr,aa,rd 1360.000368277s
[INFO] 10.1.28.1:53086- 4863"A IN mrkaran.cluster.local. udp 39 false 512" NXDOMAIN qr,aa,rd 1320.000355344s
[INFO] 10.1.28.1:56863- 41678"A IN mrkaran. udp 25 false 512" NXDOMAIN qr,rd,ra 1000.034629206s

由于 mrkaran 没有指定任何内容。因此使用搜索列表来找到答案。

注意:ndots 的值默认为 15,在 Kubernetes 中默认为5。

如果您的应用程序具有大量的外部网络调用,那么在流量繁忙的情况下,DNS 可能会成为瓶颈,因为在触发真正的 DNS 查询之前还会进行很多额外的查询。应用程序在域名中附加根域的情况很少见,但可以将这种方式看成一种 hack 方式,我们可以将应用程序硬编码为以 . 结尾的域名,比如 api.twitter.com.,而不是使用 api.twitter.com,这将会强制 DNS 客户端直接在绝对域上进行查询。

另外自 Kubernetes 1.14 起, dnsConfigdnsPolicy 特性已经很稳定了。因此,在部署 Pod 时,我们可以将 ndots 设置为较小的值(例如3),甚至可以将其设置为1,但是这样的话每个节点内通信现在都必须包含完整的域名,我们需要在性能和可移植性之间进行一些平衡。如果应用程序不考虑极低的延迟,您根本也不必担心这一点,因为 DNS 结果也会在内部缓存的。

参考文档:

1. https://github.com/kubernetes/kubernetes/issues/33554#issuecomment-266251056 2. https://pracucci.com/kubernetes-dns-resolution-ndots-options-and-why-it-may-affect-application-performances.html 3. https://www.openwall.com/lists/musl/2017/03/15/3

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 k8s技术圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档