暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

我眼中的DNS

652

如果问公有云和私有云最大的不同是什么,我的回答可能会出乎大多数人的意料,是DNS加TLS

关于这个论断的阐述又可展开好几篇文章,此处暂且按下不表。

DNS既是现代互联网的基石之一,又在私有云向公有云过渡的过程中扮演着关键角色,还常常跟TLS这个神神叨叨的小伙伴手拉手一起走,如果不了解清楚,实在是不好再自称专业 ㄟ( ▔, ▔ )ㄏ

上帝在第八天上午创造了IP协议,然后在下午发现地址太多了根本记不住,于是便有了DNS这个补丁。

移动电话普及之前,三指厚的黄页除了垫桌腿和压泡面以外还有着正常的用途,人们通过这些每年修订再版一次的电话簿维持着熟悉名字与抽象号码之间的简单映射。在计算机的上古时代,这种习惯依旧延续,每台主机上都有一个Hosts文件,里面记录着其他主机的名字和它们的IP地址。这个机制一直被保留至今,只是已经很少再被用到,除了一些不那么磊落的场景。

随着网络里面的主机越来越多,这种简单的方法很快便难以为继:

  • 人们必须不断地手动更新和添加条目

  • 当某个地址悄悄地发生了变化,没有人会知道

  • 随着时间的推移,文件的体量也越来越大,里面充斥着无效的、矛盾的、错误的记录

直到有一天,一切归入混沌,像极了你上个项目的代码库。

于是在上世纪七十年代,有人提出了集中式名字服务的概念,所有的名字与真实地址之间的映射都在一个统一的地方维护,客户端只需要知道名字服务器的地址和一个好记的名字,就能找到想访问的任意一台主机。集中管理的名字服务确实比分布式但没有管理的Hosts文件好太多了,但是做了一辈子技术又机智如你的干饭人一定也觉察到了这后面的陷阱。

没有人希望自己的系统里面存在单点,尤其是如此重要的系统,现代人离开手机五分钟就会出现明显的戒断反应,无法想象整个互联网瘫痪一小时会怎样。

于是很自然地,有了分布式名字服务的方案,网络中存在着多个功能完整的对等节点,当某个节点不再好好工作,别的奋斗节点会争相恐后地接替它。但即便如此,依然存在着一些问题:

  • 随着网络的规模越来越大,每台名字服务器都需要维护海量的地址条目,将几百亿条数据放到同一张表里无论对存储还是查找都显然不是一个太好的主意(喊ATP的那位同学,你坐下!)

  • 朴素的二八原则在所有领域都几乎适用,虽然每一个名字都是生而平等的,但就是有一些名字出现的频次更高,还有一些名字的地址万年不变……为了提升性能,需要有机制来分担和缓存这些重复的冷热不均的查找

  • 集中式管理是一个相对的概念,我们在前面已经讨论过了集中式名字服务的优势,但是当名字和地址条目的数量超过一定的规模,这种集权式的管理带来的流程损耗会超过它带来的效率提升,人们需要能够将名字按照类别(域)甚至子类交给不同的组织或个人管理,以此来提升独立性、专业性和灵活性

计算机领域有一句名言,计算机科学中的任何问题,都可以通过增加一个外(中)包(间)公(层)司来解决。

现代的域名系统(DNS),是一个树形分层半集中式管理的分布式系统

域名(Domain Name)指具有特定用途的名字,区别于一般的名字,强调其类别和功能属性。尽管常常被无意或者有意地忽略,完整的域名(FQDN)以“.”结尾,并且“.”本身也是一个特殊的域名,根域名。所有的域名都以树的形式来组织,这是DNS系统中的四棵树之一。根域名的直接子节点被称作顶级域名(TLD),最常见的是cn、us、jp这样的国家码顶级域名(ccTLD)和com、net、org这样的一般顶级域名(gTLD)。顶级域名的直接子节点被称为二级域名(SLD/2LD),依此类推。

与域名类似,并且常常被与之混淆的另一个重要概念是区域(Zone)

区域将DNS划分成一个个可以委托给组织或个人管理的单元,并形成另一棵树。

区域可以非常大,比如根区域包含所有的顶级域名,com区域包含所有以com结尾的二级域名;区域也可以很小,比如上图的example.com区域里可以只包含example.com这一个域名。根区域和TLD区域一般由ICANN这样的国际组织或者国家机构来管理,一些小的区域则可以直接委托给组织或个人,这种半集中式的管理既能提供必要的权威性和稳定性,又能给予普通域名管理者最大限度的灵活性和主动权。

通常,一个二级域名和它的下级域名都被放到同一个区域内管理。但是如果某个子域名代表相对独立的业务或部门,比如上图中的*.cloud.oracle.com,也可以单独拿出来组成独立的区域。

区域是域名管理的逻辑概念,为区域中的域名提供解析服务的,是由现实世界中的组织或个人运营的DNS服务,它们通常由一组服务器组成高可用的集群。这些物理实体,通过NS记录SOA记录串联成DNS系统中的第三棵树。一个域名的NS记录,指向负责解析这个域名的(一组)服务器的地址;而SOA记录,则记录了这组服务器之间同步数据的规则。

解析一个域名,需要先知道它的NS记录,才能得知该去哪里查询。而这个NS记录需要到上一级域名的DNS服务器去查,也就是说需要先得到上一级域名的NS记录,也就是说需要先得到上上一级域名的NS记录,也就是说需要先得到上上上一级域名的NS记录……看上去我们似乎陷入了无尽循环,永远也得不到答案。

其实,对任何域名的查询,最终都会演变成对根域名“.”的NS记录的查询目前全世界一共有13组根域名服务器,分别是a.root-servers.net到m.root-servers.net。由于这些域名对应的IP地址几乎从不改变(历史上只变化过几次),更不可能同时改变,所以它们一般都被硬编码在DNS客户端里。即使个别地址发生了变化,也不影响功能,而且在下次软件更新的时候就会得到修正,就是如此暴力又朴实无华 ㄟ( ▔, ▔ )ㄏ

以下是一次完整的DNS查询过程:

【代码】

dig +traceA frostylagoon.com

; <<>> DiG9.16.1-Ubuntu <<>> +trace A frostylagoon.com

;; global options: +cmd

.                       2243    IN     NS      i.root-servers.net.

.                       2243    IN     NS      c.root-servers.net.

.                       2243   IN      NS      m.root-servers.net.

.                       2243    IN     NS      k.root-servers.net.

.                       2243    IN     NS      a.root-servers.net.

.                       2243    IN     NS      b.root-servers.net.

.                       2243    IN     NS      e.root-servers.net.

.                       2243    IN     NS      j.root-servers.net.

.                       2243    IN     NS      l.root-servers.net.

.                       2243    IN     NS      f.root-servers.net.

.                       2243    IN     NS      g.root-servers.net.

.                       2243    IN     NS      h.root-servers.net.

.                       2243    IN     NS      d.root-servers.net.

;; Received 262 bytesfrom 127.0.0.53#53(127.0.0.53) in 3 ms

com.                    172800  IN     NS      h.gtld-servers.net.

com.                    172800  IN     NS      j.gtld-servers.net.

com.                    172800  IN     NS      a.gtld-servers.net.

com.                    172800 IN      NS      f.gtld-servers.net.

com.                    172800  IN     NS      d.gtld-servers.net.

com.                    172800  IN     NS      m.gtld-servers.net.

com.                    172800  IN     NS      i.gtld-servers.net.

com.                    172800  IN     NS      b.gtld-servers.net.

com.                    172800  IN     NS      g.gtld-servers.net.

com.                    172800  IN     NS      c.gtld-servers.net.

com.                    172800  IN     NS      e.gtld-servers.net.

com.                    172800  IN     NS      k.gtld-servers.net.

com.                    172800  IN     NS      l.gtld-servers.net.

;; Received 1176 bytesfrom 202.12.27.33#53(m.root-servers.net) in 39ms

 

frostylagoon.com.       172800 IN      NS      ns17.domaincontrol.com.

frostylagoon.com.       172800 IN      NS      ns18.domaincontrol.com.

;; Received 734 bytesfrom 192.55.83.30#53(m.gtld-servers.net) in 307ms

 

frostylagoon.com.       600    IN      A       34.102.136.180

;; Received 113 bytesfrom 173.201.76.9#53(ns18.domaincontrol.com) in295 ms

为了查询frostylagoon.com这个域名的A记录(IPv4地址),需要先知道frostylagoon.com的NS记录,需要先知道com的NS记录,需要先知道“.”的NS记录。根域名“.”的NS记录我们已经提前知道了,于是便可以一路反推回去,最终从com域名的DNS服务器那里得知frostylagoon.com的A记录保存在ns17.domaincontrol.com和ns18.domaincontrol.com这两台主机上。最后,从它们之中任选一台,终于查到了我们想要的地址。

大多数情况下,DNS服务器的地址也是用域名表示的,这意味着除了上面提到的查询步骤,为了得到服务器自身的IP地址,我们还需要进行更多额外的查询。

这种查询过程被称为迭代查询(Iterative Query),整个过程看上去繁琐又低效,事实也的确如此。但是作为普通终端用户,在实际场景中,我们一般会借助另外一种叫做DNS Resolver的服务来代替我们完成这个过程,并且通过TTL缓存机制尽可能共享和复用查询结果,这种方式叫做递归查询(Recursive Query)

所有的DNS Server都支持迭代查询,但是只有DNS Resolver才支持递归查询。所有的DNS Resolver都是DNS Server,但不是所有的DNS Server都是DNS Resolver。大名鼎鼎的8.8.8.8和114.114.114.114就是DNS Resolver。

如果不手工指定,默认的DNS Resolver通常由路由器或者网关来担任。各级Resolver和Server之间通过TTL与缓存机制构成了DNS系统的第四颗树。

本文沿着DNS发展的历史脉络,介绍了系统中的重要概念和主要的记录类型,并总结出“四棵树”,希望能够对读者了解DNS有所助力。DNS是研究大规模高可用分布式系统设计的鲜活范例,还有足够多的主题可以深入挖掘,更多内容请期待后续文章。


作者简介

宋晓寒,甲骨文云架构团队高级咨询顾问,负责甲骨文云平台产品和解决方案的咨询和推广。有通信、智能硬件、物联网以及零售供应链领域多年的从业经历,在加入甲骨文之前是一名连续创业者,目前主要关注跨平台移动化开发、智能制造和机器学习等方向。您可以通过xiaohan.song@oracle.com与他取得联系。


扫描二维码或点击阅读原文

快速预约精选云解决方案演示


文章转载自甲骨文开发者社区,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论