18143453325 在线咨询 在线咨询
18143453325 在线咨询
所在位置: 首页 > 营销资讯 > 建站知识 > DNS协议深度解析

DNS协议深度解析

时间:2023-02-02 15:28:01 | 来源:建站知识

时间:2023-02-02 15:28:01 来源:建站知识

DNS(Domain Name System)是互联网的基础核心协议之一,我们在日常工作不知不觉中经常使用到该协议,我们需要对其有很好的了解。那么他的主要用途是什么呢?都应用在哪些方面呢?下面我们先来了解一下 DNS 协议及其原理。

1. DNS原理

在现实世界中,我们如果需要找到一个餐厅。我们大多数情况会在大众点评中搜索这个餐厅,大众点评的“地址薄”会返回给你一个非常详细的地址,比如:广东省深圳市南山区 XX 路 XX 号。那么在网络世界中,我们如果要记住一个网站,不大可能记住他的 IP 地址,况且如果他的 IP 变动了,我们又需要记住新的 IP 地址。

所以 DNS 是整个互联网的地址簿,它能够将可被人理解的域名翻译成可被机器理解 IP 地址,使得大家不再需要记住 IP 地址,另外当 IP 地址发生改变时,我们可以在其发生变动时修改地址薄中“地址”和 IP 地址的关系,那么我们就可以保证对外提供的服务能够相对稳定地被其他客户访问。

从这里我们也可以看出来 DNS 在日常生活中多么重要。每个人上网,都需要访问它,但是同时,这对它来讲也是非常大的挑战。一旦它出了故障,整个互联网都将瘫痪。所以 DNS 服务器一定要设计成一个 高可用,高并发,分布式的架构。

于是就有了下面这个树状层次结构:

如图树的最顶层是根域名,一般使用 . 来表示,所以当我们在请求的域名时一般写为 http://node1.cluster.example.com,但是这里的写法其实省略了最后的 .,也就是全称域名(FQDN)node1.cluster.example.com.

根域名下面的就是 com、net、cn 等顶级域名以及次级域名 http://example.com,我们一般在各个域名网站中购买和使用的都是次级域名、子域名和主机名了。

既然 DNS 是树形的层次结构,所以 DNS 服务也是树形的并且每一层职责是不通的。DNS 解析器从根域名服务器查找到顶级域名服务器的 IP 地址,又从顶级域名服务器查找到权威域名服务器的 IP 地址,最终从权威域名服务器查出了对应服务的 IP 地址。比如 Google 中国主页所使用的域名是:http://www.google.cn,那么当我们请求 DNS 服务器的时候,他是如何一步步的获得IP地址的呢?

我们可以在 Linux/MacOS 中使用 dig 命令追踪一下:

AlandeMacBook-Pro:~ alan$ dig -t A www.google.cn +trace; <<>> DiG 9.10.6 <<>> -t A www.google.cn +trace;; global options: +cmd. 57 IN NS a.root-servers.net.. 57 IN NS d.root-servers.net.. 57 IN NS i.root-servers.net.. 57 IN NS j.root-servers.net.. 57 IN NS c.root-servers.net.. 57 IN NS g.root-servers.net.. 57 IN NS k.root-servers.net.. 57 IN NS l.root-servers.net.. 57 IN NS h.root-servers.net.. 57 IN NS b.root-servers.net.. 57 IN NS f.root-servers.net.. 57 IN NS e.root-servers.net.. 57 IN NS m.root-servers.net.;; Received 228 bytes from 223.5.5.5#53(223.5.5.5) in 57 mscn. 172800 IN NS a.dns.cn.cn. 172800 IN NS b.dns.cn.cn. 172800 IN NS c.dns.cn.cn. 172800 IN NS d.dns.cn.cn. 172800 IN NS e.dns.cn.cn. 172800 IN NS f.dns.cn.cn. 172800 IN NS g.dns.cn.cn. 172800 IN NS ns.cernet.net.cn. 86400 IN DS 57724 8 2 5D0423633EB24A499BE78AA22D1C0C9BA36218FF49FD95A4CDF1A4AD 97C67044cn. 86400 IN RRSIG DS 8 1 86400 20211120050000 20211107040000 14748 . RsJoclM7GXR5uwuTeTwmDt09HTxQXG+dIKA3aCI9E7YPIFqCCuoW3iwA HA9FeNDUoznV+YvAZsMQA+mgwtBdrUWiABuVT69Zv3ye9KBQaLpUV3fQ iNikwG1KAFke2SJ0sH8+7OTTIFoHsWhbmfGWOJiYlaO27FGKjwRDQBgL /GNAYx8Mw7yKvt1qXWHBa8G8d1Xa9GLDYTv3m3zoEPn5rNwYo/I/QTNm J5dFmngsLDS+gPVz5L2u2EGnBPorbipmZrG2xnC9DXLX9Oafk+Ex/RaL /qErKsq6DfJrPruiAbCCbhzPEPBRiq4y/8rjT1sJEmzmnMz/MFX2CmgV wtLYCw==;; Received 704 bytes from 192.58.128.30#53(j.root-servers.net) in 393 msgoogle.cn. 86400 IN NS ns1.google.com.google.cn. 86400 IN NS ns3.google.com.google.cn. 86400 IN NS ns2.google.com.google.cn. 86400 IN NS ns4.google.com.3QDAQA092EE5BELP64A74EBNB8J53D7E.cn. 21600 IN NSEC3 1 1 10 AEF123AB 3QM14FQ32F1CJFTP8D3J5BCTNP5BIELO NS SOA RRSIG DNSKEY NSEC3PARAM3QDAQA092EE5BELP64A74EBNB8J53D7E.cn. 21600 IN RRSIG NSEC3 8 2 21600 20211203071642 20211103061642 38388 cn. qyrAppcU/gK8pzkFh+SkyX+rkvFSyeBK3c9r4XKAzO7QFkh5Hw/aVydP 2nEApdBhFvG2DbH/YVS81XOtiFQkhBmIL6vyByLUGGFcAgn3a7mgIx0n +8Ae2FWLogR0gRRNisU1obpVEvEG9G47fpEZ9iVifc2pLT+ekz3EOJnj N+k=8TKMCNJ923RR3GI4UAK4FF8RHB788CNF.cn. 21600 IN NSEC3 1 1 10 AEF123AB 8UHOOPIE1URLUSVICNFBIDOLA9HMRV82 CNAME RRSIG8TKMCNJ923RR3GI4UAK4FF8RHB788CNF.cn. 21600 IN RRSIG NSEC3 8 2 21600 20211203071642 20211103061642 38388 cn. Jy9qk55fGKqi/iuJuefBQXGKw0GJkmRDxguQDGmWLBwrdUj7hJjWJiP9 5hvYe96UNgnSm5cPdYXUe/yL2X8jPyYxXJW/bf/uHKK65jwnnEGghkS4 yDVkSCWOsDU2gmGdmm5ytga4xcl1ZNx8+98fhTir49m/uo93DqB7CRin oHQ=;; Received 615 bytes from 66.198.183.65#53(g.dns.cn) in 294 mswww.google.cn. 300 IN A 180.163.150.162;; Received 58 bytes from 216.239.32.10#53(ns1.google.com) in 54 ms我们可以看出,首先会向预置的 13 组根域名服务器发出请求获取顶级域名的地址:

;; global options: +cmd. 57 IN NS a.root-servers.net.. 57 IN NS d.root-servers.net.. 57 IN NS i.root-servers.net.. 57 IN NS j.root-servers.net.. 57 IN NS c.root-servers.net.. 57 IN NS g.root-servers.net.. 57 IN NS k.root-servers.net.. 57 IN NS l.root-servers.net.. 57 IN NS h.root-servers.net.. 57 IN NS b.root-servers.net.. 57 IN NS f.root-servers.net.. 57 IN NS e.root-servers.net.. 57 IN NS m.root-servers.net.;; Received 228 bytes from 223.5.5.5#53(223.5.5.5) in 57 ms根域名服务器(root name server)是互联网域名解析系统(DNS)中最高级别的域名服务器,负责返回顶级域的权威域名服务器地址。它们是互联网基础设施中的重要部分,因为所有域名解析操作均离不开它们。由于 DNS 和某些协议(未分片的用户数据报协议(UDP)数据包在 IPv4 内的最大有效大小为512字节)的共同限制,根域名服务器地址的数量被限制为 13 个。幸运的是,采用任播技术架设镜像服务器可解决该问题,并使得实际运行的根域名服务器数量大大增加。截至2019 年 8 月,全球共有 1008 台根域名服务器在运行。(具体这13个服务器的IP地址以及运营商请参考这里:https://www.iana.org/domains/root/servers

由于中国互联网发展的较晚,国内没有根服务器,为了防止其他国家因为政治原因打击中国,从而对中国互联网产生重大打击。截至 2021 年 7 月,中国共有F、I、J、K、L这5个根域的 21 台 DNS 镜像在提供服务。
而通过根服务器(http://j.root-servers.net),我们获得了 13 个cn.定义的顶级 DNS 服务器:

cn. 172800 IN NS a.dns.cn.cn. 172800 IN NS b.dns.cn.cn. 172800 IN NS c.dns.cn.cn. 172800 IN NS d.dns.cn.cn. 172800 IN NS e.dns.cn.cn. 172800 IN NS f.dns.cn.cn. 172800 IN NS g.dns.cn.cn. 172800 IN NS ns.cernet.net.cn. 86400 IN DS 57724 8 2 5D0423633EB24A499BE78AA22D1C0C9BA36218FF49FD95A4CDF1A4AD 97C67044cn. 86400 IN RRSIG DS 8 1 86400 20211120050000 20211107040000 14748 . RsJoclM7GXR5uwuTeTwmDt09HTxQXG+dIKA3aCI9E7YPIFqCCuoW3iwA HA9FeNDUoznV+YvAZsMQA+mgwtBdrUWiABuVT69Zv3ye9KBQaLpUV3fQ iNikwG1KAFke2SJ0sH8+7OTTIFoHsWhbmfGWOJiYlaO27FGKjwRDQBgL /GNAYx8Mw7yKvt1qXWHBa8G8d1Xa9GLDYTv3m3zoEPn5rNwYo/I/QTNm J5dFmngsLDS+gPVz5L2u2EGnBPorbipmZrG2xnC9DXLX9Oafk+Ex/RaL /qErKsq6DfJrPruiAbCCbhzPEPBRiq4y/8rjT1sJEmzmnMz/MFX2CmgV wtLYCw==;; Received 704 bytes from 192.58.128.30#53(j.root-servers.net) in 393 ms再通过上述的顶级 DNS 服务器(http://g.dns.cn)一共获得 4 个权威 DNS 服务器的地址:

google.cn. 86400 IN NS ns1.google.com.google.cn. 86400 IN NS ns3.google.com.google.cn. 86400 IN NS ns2.google.com.google.cn. 86400 IN NS ns4.google.com.3QDAQA092EE5BELP64A74EBNB8J53D7E.cn. 21600 IN NSEC3 1 1 10 AEF123AB 3QM14FQ32F1CJFTP8D3J5BCTNP5BIELO NS SOA RRSIG DNSKEY NSEC3PARAM3QDAQA092EE5BELP64A74EBNB8J53D7E.cn. 21600 IN RRSIG NSEC3 8 2 21600 20211203071642 20211103061642 38388 cn. qyrAppcU/gK8pzkFh+SkyX+rkvFSyeBK3c9r4XKAzO7QFkh5Hw/aVydP 2nEApdBhFvG2DbH/YVS81XOtiFQkhBmIL6vyByLUGGFcAgn3a7mgIx0n +8Ae2FWLogR0gRRNisU1obpVEvEG9G47fpEZ9iVifc2pLT+ekz3EOJnj N+k=8TKMCNJ923RR3GI4UAK4FF8RHB788CNF.cn. 21600 IN NSEC3 1 1 10 AEF123AB 8UHOOPIE1URLUSVICNFBIDOLA9HMRV82 CNAME RRSIG8TKMCNJ923RR3GI4UAK4FF8RHB788CNF.cn. 21600 IN RRSIG NSEC3 8 2 21600 20211203071642 20211103061642 38388 cn. Jy9qk55fGKqi/iuJuefBQXGKw0GJkmRDxguQDGmWLBwrdUj7hJjWJiP9 5hvYe96UNgnSm5cPdYXUe/yL2X8jPyYxXJW/bf/uHKK65jwnnEGghkS4 yDVkSCWOsDU2gmGdmm5ytga4xcl1ZNx8+98fhTir49m/uo93DqB7CRin oHQ=;; Received 615 bytes from 66.198.183.65#53(g.dns.cn) in 294 ms最后通过 Google 的 DNS 服务器(http://ns1.google.com)返回他的 IP 地址:

www.google.cn. 300 IN A 180.163.150.162;; Received 58 bytes from 216.239.32.10#53(ns1.google.com) in 54 ms从整个解析过程,我们可以看出 DNS 域名服务器大体分成三类,根域名服务、顶级域名服务以及权威域名服务三种,获取域名对应的 IP 地址时,也会像遍历一棵树一样按照从顶层到底层的顺序依次请求不同的服务器。

所以整个过程如过用一副图表述的话,整体过程如下图:

上图中第一步本地 DNS 解析器先查看看本地的缓存是否有这个记录。如果有则直接使用,因为上面的过程太复杂了,如果每次都要递归解析,那么速度就太慢了。如果本地无缓存,则需要请求本地的 DNS 服务器。

第三步本地的 DNS 服务器一般是你所在的运营商(中国电信/联通/移动等)提供的,当然现在也有很多公共 DNS(比如国内很出名的:114.114.114.114,阿里云223.5.5.5;国外很出名的:Google 8.8.8.8。),本地 DNS 服务器也需要看本地是否有缓存,如果有则返回,因为它也不想把上面的递归过程再走一遍。




2. HTTPDNS

然后传统的 DNS 协议存在一些已知的问题:

1.本地缓存问题

根据上面的介绍我们知道他并不是每个请求都会访问根、顶级、权威 DNS 服务器,他会访问过一次后就把结果缓存到自己本地。当其他人再次来访问的时候,他就会立即返回缓存的数据。这就相当于你问一个人某餐厅在哪里?他凭借自己的记忆给你说了一个地方,但是可能这个餐厅已经换地址了。

还有一种情况,用长城宽带,移动宽带的朋友经常遇到的一个问题。这些运营商通常会把一些静态页面,视频缓存到他们的服务器内,这样用户请求的时候,就不用跨运营商进行访问,这样既加快了速度,也减少了运营商之间流量计算的成本。在域名解析的时候,不会将用户导向真正的网站,而是指向这个缓存的服务器。很多情况下是看不出问题的,但是当视频或者页面更新了,我们就会访问到老的页面。

还有就是会导致最短路径失效,上次缓存的IP地址可能不是离客户最近的,这样客户的访问速度就会受到影响,从而影响用户的体验。

2.域名劫持

当我们向外部发出请求解析 DNS 的时候,首先会先连接到本地运营商的 DNS 服务器(如电信/联通/移动),由他们的 DNS 服务器帮我们去根和顶级 DNS 服务器解析,然后将解析的结果返回给客户端。但如果这些本地运营商在其 DNS 服务器上有一些自己的想法,比如想推送个广告呢?这样他就可以轻易的劫持你的 DNS请求,达到自己的一些“小需求”,这就是我们常说的运营商劫持。

3.DNS解析更新

本地运营商 DNS 服务器对域名解析缓存的处理上,实现策略是有所区别的,有的会忽略域名解析结果的 TTL 时间限制,在权威 DNS 服务器解析变更的时候,因而导致解析结果在全网生效的周期非常漫长。但是在 DNS 的切换中,某些情况对生效时间要求又比较高。例如异地灾备业务部署的时候,跨地区数据库,负载均衡的切换一般通过 DNS 解析来实现。当一个区域出问题后,需要修改 DNS 解析,将数据库,负载均衡等域名指向新的 IP 地址,但是如果更新太慢,那很多用户都会出现访问异常。




针对以上的情况,就催生了 HTTPDNS。HTTPDNS 一般是基于 Http 协议向自己搭建或者公有云服务商提供的基于 HTTP 协议的 DNS 服务器集群,分布在多个地点和多个运营商的 DNS 服务器发送域名解析请求,替代了基于 DNS 协议向本地运营商 Local DNS 发起解析请求的传统方式,可以避免了本地运营商 Local DNS 造成的域名劫持和跨网访问问题,解决移动互联网服务中域名解析异常带来的困扰,同时还可以实现域名解析快速生效,以及智能调度实现用户获取离他最近的IP地址。

而 HTTPDNS 特别是适合移动 APP 端复杂的网络条件,既能做到加速解析和加速更新,还能做到精准调度,以及避免运营商劫持。一般可以为 iOS 和 Android 的应用APP 提供 SDK 接入,而服务端以及非主流客户端接入一共通过 HTTPS API的方式接入。SDK 的接入非常的方便,这样就可以通过 SDK 来做到如何更新、何时更新,APP 客户端可以和服务器协调来做这件事情,而不受制于电信运营商。

下面我们通过 API 接入 HTTPDNS 的最佳实践简单了解一下 HTTPDNS 的请求过程:

通过上图,我们可以看到整个解析过程非常的简单,不需要向根、顶级、权威 DNS 服务器发送请求。只想要向 HTTPDNS 接口发送请求即可,大幅缩短了请求路径,提高了性能。

以上便是目前解决 DNS 协议使用后遇到的一些问题的一种有效的解决方法--HTTPDNS。

3. Kubernest中的DNS

而 DNS 作为一种常见的服务发现手段,很多开源项目都会使用 DNS 为集群提供服务发现的功能,Kubernetes 就在集群中使用 DNS 解决服务发现的问题。如果使用常规的 DNS 服务,就会存在上面说的延迟问题,所以目前 Kubernetes 启动一个单独的 DNS 服务--CoreDNS。




CoreDNS 在 Kubernetes 1.12版本之后成为默认 DNS 服务。他是使用 Golang 编写的基于 Caddy 服务器框架实现的一个插件链的架构的应用,就像其官方文档上写的一样:CoreDNS is powered by plugins. 其主要有3个特点:

1.插件化,开发者只要按照 CoreDNS Plugin API编写自定义插件,就可以很方便地集成到 CoreDNS 中。

2.完整的解决方案,其内置了缓存、后端存储管理和健康检查等功能,无需第三方插件实现。

3.配置简单

作为集群部署完成后第一个容器化的应用,其为整个集群提供了稳定,可靠的 DNS 服务。

下面我们来一起看一下 CoreDNS 的工作流程:

.:53 { errors health kubernetes cluster.local. in-addr.arpa ip6.arpa { pods insecure upstream fallthrough in-addr.arpa ip6.arpa } prometheus :9153 forward . /etc/resolv.conf cache 30 reload loadbalance}example.io:53 { errors log file /etc/coredns/zones/example.io.db}coredns.io:5300 { file /etc/coredns/zones/coredns.io.db}通过上面的 Corefile,我们可以看出一共定义了 2 个 DNS Server,但有3个配置块,分别监听的是 53 和 5300 端口,那么 CoreDNS 又是怎么解析这个配置的呢?

可以看出 Coredns 会根据不同的域名选择不同区中的插件进行处理。这充分体现了其插件化的架构设计。




Kubernets 中 DNS 策略可以在每个 Pod 基础上进行设置,目前,Kubernetes支持Default、ClusterFirst、ClusterFirstWithHostNet和None四种DNS策略,具体请参见https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/。这些策略在 pod-specific 的 dnsPolicy 字段中指定。

Tips:“Default”不是默认的DNS策略。如果dnsPolicy的Flag没有特别指明,则默认使用“ClusterFirst”。




所以他的请求流程是:

未配置存根域:没有匹配上配置的集群域名后缀的任何请求,例如 “www.google.cn”,将会被转发到继承自节点的上游域名服务器。

已配置存根域:如果配置了存根域和上游 DNS 服务器,DNS 查询将基于下面的流程对请求进行路由:

首先被发送到 CoreDNS 中的 DNS 缓存层。

从缓存层,检查请求的后缀,并根据下面的情况转发到对应的 DNS 上:

其整体过程如下图:

以上便是 Kubernetes 中 DNS 解析的策略,那么其具体的 DNS 解析是如何进行的呢?由于 Pod 默认会根据 /etc/resolve.conf 来进行解析过程,我们先看一个 Pod的 /etc/resolve.conf 的文件内容:

nameserver 10.6.98.183search default.svc.cluster.local svc.cluster.local cluster.localoptions ndots:5第一行 nameserver 就是CoreDns的Service的ClusterIP,而第二行便是搜索域。

Kubernetes 中,域名的全称,必须是 service-name.namespace.svc.cluster.local 这种模式,服务名,就是Kubernetes中 Service 的名称。所以我们执行

curl nginx-democurl nginx-demo.default他们的流程分别是:

首先会通过 10.6.98.183 这个 nameserver 进行解析,然后将nginx-demo带入search的搜索域进行dns解析。过程分别是:

nginx-demo.default.svc.cluster.local

nginx-demo.svc.cluster.local

nginx-demo.cluster.local

所以通过这个过程,我们在请求 nginx-demo 和 nginx-demo.default 时,明显直接请求服务名称会更快,效率更高。因为 nginx-demo.default 第一次请求是 nginx-demo.default.default.svc.cluster.local,到第二次才是正确的:nginx-demo.default.svc.cluster.local,所以这点我们在平时使用中需要特别注意。

上面说的是Kubernetes 内部服务的DNS解析请求,那么如果访问外部的域名呢?比如请求http://www.google.cn呢?他有时如何工作的呢?


其实他的请求路径是:

www.google.cn.default.svc.cluster.local

www.google.cn.svc.cluster.local

www.google.cn.cluster.local

www.google.cn.

可以看出来,有3次请求是无意义的请求。那么为什么会出现这种情况呢?就要回头去看 /etc/resolve.conf 中的最后一行。

options ndots:5这一行的含义是:如果查询的域名包含的点“.”,不到5个,那么进行DNS查找,将使用非完全限定名称(或者叫绝对域名),如果你查询的域名包含点数大于等于5,那么 DNS 查询,默认会使用绝对域名进行查询。

那么我们如何避免这种查询浪费呢?其实很简单,只需要在请求的域名后面加上".",如:www.google.cn. 这样子就能避免走 search 域进行匹配,从而提升效率。所以我们需要在编写应用代码时,应该硬编码为包含"."。




4.总结


本文详细介绍了 DNS 的解析原理以及目前 DNS 存在一些缺陷,并通过介绍HTTPDNS 这种新的方式来有效的解决这些缺陷。同时介绍了 Kubernets 中 DNS 的路由策略和解析过程。

欢迎继续关注我的微信公众号 矢量SRE



关键词:深度,协议

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭