一次 DNS 解析超时引发的线上告警

💡 原文中文,约4600字,阅读约需11分钟。
📝

内容提要

周五下午,某核心服务的P99延迟骤增至2秒,原因是DNS解析问题。Go语言的默认DNS解析器在特定环境下可能导致延迟,K8s的ndots值为5,导致外部域名解析失败。最终通过修改域名和配置DNS缓存解决了问题。

🎯

关键要点

  • 周五下午某核心服务的P99延迟骤增至2秒,原因是DNS解析问题。

  • Go语言有两套DNS解析器,分别是纯Go实现和通过cgo调用系统的getaddrinfo函数。

  • K8s的ndots值为5,导致外部域名解析失败,增加了DNS查询的次数。

  • CoreDNS在处理大量DNS请求时响应延迟增加,导致接口的P99延迟上升。

  • 可以通过在外部域名后加点、修改ndots值或使用DNS缓存来解决问题。

  • 最终采取的方案是外部域名加点和部署NodeLocal DNSCache,降低ndots值至2。

  • DNS解析的逻辑导致外部域名请求变慢,需注意配置环境的影响。

延伸问答

DNS解析问题是如何导致核心服务延迟增加的?

DNS解析问题导致核心服务的P99延迟从50ms飙升至2s,主要是因为K8s的ndots值设为5,导致外部域名解析失败,增加了DNS查询次数。

Go语言的DNS解析器有哪些不同之处?

Go语言有两套DNS解析器:一套是纯Go实现,直接读取/etc/resolv.conf;另一套是通过cgo调用系统的getaddrinfo函数,依赖操作系统的DNS解析流程。

如何通过修改ndots值来解决DNS解析问题?

可以将K8s的ndots值从5降至2,这样外部域名的点数不再少于ndots,直接使用原始域名查询,避免走search domain拼接。

NodeLocal DNSCache的作用是什么?

NodeLocal DNSCache在每个节点上运行一个DNS缓存Pod,所有DNS请求先到本地缓存,命中后直接返回,减少了对CoreDNS的请求,提高了响应速度。

在K8s中,如何配置DNS以避免解析延迟?

可以在K8s的Pod spec中自定义DNS配置,设置dnsConfig选项,将ndots值降至2,或在外部域名后加点以避免search domain拼接。

DNS解析的逻辑是如何影响外部域名请求的速度的?

DNS解析逻辑会根据ndots值判断域名是否完整,若不完整则进行多次拼接查询,导致外部域名请求速度变慢,尤其在DNS服务器响应变慢时更为明显。

➡️

继续阅读