问题描述
最近在协助用户做业务的容器化迁移时,对业务做压力测试,发现ui服务的/homepage接口出现了偶发性的响应请求超时。给大家分享下排查问题过程。
问题定位
先通过skywalking看看相关ui的/homepagetrace,通过下图可以看到总耗时超过5828ms。
发现延时出现在ui/homepage的self上,共耗时4005ms。其他依赖调用的时间只用了1823ms。可以确认从ui/homepage调用app/homepage的请求发生到请求数据传输完成耗时太多。现在没有更好的方法进一步排查具体的耗时情况,进入ui容器内,只能使用curl访问app/homepage看看。
$curl -4 -w "@curl-format.txt" -o /dev/null -l "http://app.default.svc.cluster.local:8091/homepage" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- 0:00:03 --:--:-- 0 time_namelookup: 4.150 time_connect: 0.800 time_appconnect: 0.000 time_redirect: 0.000 time_pretransfer: 0.021 time_starttransfer: 0.000 ---------- time_total: 4.981
直接在pod中使用tcpdump抓包,使用wireshark分析结果如下:
- app.default.svc.cluster.local 域名解析成IP的总共耗时4.1s。
- 在app.default.svc.cluster.local 的基础上,依次添加default.svc.cluster.local、svc.cluster.local、cluster.local、openstacklocal 后缀进行域名解析,都失败了。
- 最后一次使用app.default.svc.cluster.local 进行解析成功了。
为啥会有多次请求DNS,百度了下发现K8S的DNS解析机制,和resolv.conf文件中ndots和search两个参数的机制作用有关系。查看容器的/etc/resolv.conf配置:
nameserver 10.96.0.10 search default.svc.cluster.local svc.cluster.local cluster.local openstacklocal options ndots:5 single-request-reopen
ndots: 5 表示如果域名包含的 "." 少于5个,则先添加 search 后缀,再使用绝对域名;如果域名包含的 "." 大于等于5个,则先使用绝对域名,再添加 search 后缀。
原因是app.default.svc.cluster.local少于5个点,所以先加search后缀。最后再使用app.default.svc.cluster.local进行解析。
解决方案
- 使用简短域名,app.default.svc.cluster.local改成app
- 修改/etc/resolv.conf配置,将ndots: 5 修改为 ndots: 4
问题复盘
DNS是Kubernetes集群中至关重要的基础服务之一,因为K8S的机制,造成DNS域名解析请求是Kubernetes最高频的网络行为之一。如果DNS有问题,很容易出现性能问题。但DNS很难通过apm等监控工具的trace定位问题,只能通过登录容器进行抓包分析,这种除了耗时耗力外,很可能相关的POD都已经消亡了。
可以实时监控DNS吗?
Kindling的eBPF探针可以实时获取到被监控POD间的所有请求,包括DNS请求。部署完成后,通过Kindling来排查DNS问题就很方便了。DNS Request Detiail 面板显示了单个K8S集群下DNS请求的监控数据。可以在此面板中分析网络的DNS性能。面板显示了DNS的关键KPI指标,例如:请求量、延时、错误数等。通过面板可以清晰了解DNS的运行状态,像前面介绍的场景可以直接看到发起了4次状态为NXDomain的DNS解析。下面通过一段视频简单介绍一下Kindling轻量版的DNS面板功能。
Kindling项目地址:Kindling
在云可观测性方面有任何疑问欢迎与我们联系:Kindling官网