域名解析和缓存

Python016

域名解析和缓存,第1张

当浏览器访问某个网站域名或者应用服务通过域名方式访问API接口的时候,需要用IP和port建立TCP连接或者复用底层连接,IP地址的获取依赖对域名的解析,完成解析的角色称为域名解析器(dns resolver)。解析的大致过程就是检查cache是否有该记录,本地hosts文件是否有,都没有命中就查询dns server进行CNAME和A记录的查询。在linux系统下,dns server的IP一般在/etc/resolv.conf文件中。

域名解析常用dig命令,以及在 https://www.whatsmydns.net/ 进行域名解析测试。

考虑到域名IP地址不是经常变动,减少查询dns的冗余,并显著降低高QPS应用服务查询dns的压力(最后一节有benchmark对比),需要对dns信息进行缓存。因为软件应用不同、开发语言不同、操作系统不同,dns resolver的实现和封装也不同,会遇到不同的层面的cache。比如windows的dns resolver会有cache,linux默认不缓存;go语言可以选择cgo或者自己实现的dns resolver;chrome浏览器也会有自己的cache。

dns cache除了好处以外,也带来了其他问题。比如dns cache可能被恶意病毒修改,将真实IP改成钓鱼网站的IP,对用户进行诱导和钓鱼。还有在服务发现的这种特定场景下,dns cache是不被允许的,会出现IP更新不及时导致API流量的损失和错误,例如部署上线或者宕机,相比之下,运维响应的时长会造成更大的损失。但为了解决这个问题,在client和server端中间增加一层代理,dns记录指向这个代理。如图:

代理职责一般有:

代理一般分为:

四层代理对外暴露的IP一般称为虚IP(VIP)

example_test.go

性能对比:

从对比中可看出:go的pure resolver因没有cache和网络不稳定的因素,总耗时较多。而cgo的resolver比较稳定且耗时较低。

linux或类unix系统是没有操作系统级别的dns cache。除非安装了dnsmasq或者

nscd(Name Service Caching Daemon),并开启。

CoreDNS 是一个DNS服务器。使用 Go 编写。

CoreDNS 和其他DNS服务器不同,比如 (其实都不错的)

BIND ,

Knot ,

PowerDNS 以及

Unbound (其实仅作为resolver, 但是还是值得关注),

因为其运行非常流畅,而且几乎所有功能都使用插件实现。

插件可以单独运行或者组合为 "DNS function" 来运行。

那么,什么是 "DNS function" 呢? 我们定义CoreDNS是实现CoreDNS 插件 API 的部分软件。功能的实现差异可以很大。

有些插件自身不作任何响应,比如 metrics 或 cache ,仅增加功能。

有些插件会发出响应(response)。这些插件功能强大:

有插件协同 Kubernetes 来提供服务发现,有插件从 file or database 读取数据。

在默认安装中,已经包含了大约30个插件。但是还有大量的 external 插件你可以编译到CoreDNS中来扩展功能。

开发新的 plugins 非常容易,但是需要懂GO语言并且深入了解DNS如何工作 。CoreDNS 抽象出了大量的DNS细节,所以你只需要关注你需要开发的功能即可。