我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第 6 篇文章,点击查看活动详情”
知道苹果为什么掉地上比被不被苹果砸到更重要,虽然即便知道了也还可能被苹果砸。
-- 来自张三的觉悟
1. 事件背景
我在 Hugo 动态数据这么玩,嘿嘿一文中解决了业务人员编写 Markdown 的窘境,但在部署上线时发现,只要请求 Hugo 页面,整个服务就会 Crash 掉,分析异常信息得到提示,调用远程接口异常,可我工作电脑访问后端 API 接口返回正常。
通过工具 Attach 到 Pod 中执行 Ping 命令,提示 host unreachable。仔细排查发现,DNS 解析出来的地址竟然是主机网段内的空 IP。病因找到了,DNS 解析异常。
2. 异常分析
kubesphere 集群中 DNS 组件逻辑关系图。看不懂没关系,跟着思路再来回顾即可。
2.1 查看 Pod DNS 解析
$ cat /etc/resolv.conf
nameserver 169.254.25.10
search wxwork.svc.alpha.pm.k8s svc.alpha.pm.k8s alpha.pm.k8s
options ndots:5
169.254.25.10 是 Node Local DNS Cache 默认绑定的 DNS 服务地址。 Node Local DNS Cache 在 k8s 集群中以 Daemonset 形式运行,Pods 可以访问在同一节点上运行的 DNS 缓存代理,从而避免 iptables DNAT 规则和连接跟踪,进而大幅度提高集群内部 DNS 解析性能。Daemonset 形式并非高可用架构,所以要注意 Node 节点资源预留。
2.2 查看 NodeLocalDNSCache ConfigMap
apiVersion: v1
data:
Corefile: |
alpha.pm.k8s:53 {
errors
cache {
success 9984 30
denial 9984 5
}
reload
loop
bind 169.254.25.10
forward . 10.233.0.3 { # 如未命中,回源
force_tcp
}
prometheus :9253
health 169.254.25.10:9254
}
in-addr.arpa:53 {
errors
cache 30
reload
loop
bind 169.254.25.10
forward . 10.233.0.3 { # 如未命中,回源
force_tcp
}
prometheus :9253
}
ip6.arpa:53 {
errors
cache 30
reload
loop
loop
bind 169.254.25.10
forward . 10.233.0.3 { # 如未命中,回源
force_tcp
}
prometheus :9253
}
.:53 {
errors
cache 30
reload
loop
bind 169.254.25.10
forward . 10.233.0.3 { # 如未命中,回源
force_tcp
}
prometheus :9253
}
kind: ConfigMap
... # 此处省略其他字段
从 Corefile 配置可以看到,所有的域名解析,如果未命中缓存,则回源到 10.233.0.3 这个地址解析,而且强制使用 TCP 协议。回源地址正是 CoreDNS 在集群中的 ClusterIP,我们顺藤摸瓜往上追踪。
将 DNS 查询从 UDP 切换 TCP 将减少由于被丢弃的 UDP 包和 DNS 超时而带来的等待时间;这类延时通常长达 30 秒(3 次重试 + 10 秒超时)。
2.3 查看 CoreDNS 配置
apiVersion: v1
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes alpha.pm.k8s in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
xxx.xxx.xxx:53 { # 重点在这里
errors
cache 30
forward . xxx.xxx.xxx.xxx
}
kind: ConfigMap
... # 此处省略公共信息
在 CoreDNS 配置中发现一段特殊配置,让我想想,这或许是张三不知道啥时候添加的,虽然他打死不承认是他干的。CoreDNS 的回源地址,是个内部早已废弃的 DNS 服务器。虫子抓到了,这虫子还是自己人养的。
总结
排查问题的过程很简单,但其背后涉及的工作原理却很复杂。如果各位对 NodeLocalDNSCache 感兴趣,还可以看看,它是如何避免 Conntrack 5 秒延迟的。相信此时,你已经看懂开篇那副图了,赶紧登录自己的 k8s 集群,看看是不是这么回事儿 !
任何配置的变更,都要有迹可循。关注大飞哥,后续更新 Gitops 系列大课程。