k8s异常DNS开销
遇到一个很牛逼的 DNS 开销问题。
某测试用 K8s 集群内,curl 测试时,DNS 延迟飞到了 20ms,也不清楚是什么原因:
以下的 test-shell 是以以下指令创设的一台设备:
kubectl --context kind-cross-test-1 run test-shell --image=debian:12 --rm -it \ ─╯
--restart=Never \
--image-pull-policy=Never \
-- \
bash
问题表征
root@test-shell:/# curl -x socks5://tailscale-proxy.default.svc.cluster.local:1055 -k -s -w "DNS: %{time_namelookup}s
TCP: %{time_connect}s
SSL: %{time_appconnect}s
TTFB: %{time_starttransfer}s
Total: %{time_total}s
" https://k8sbc.default.svc.cross-test-1.remote
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-59689497fb-9486x | v=1
DNS: 0.024277s # 超绝异常 DNS 延迟!!
TCP: 0.024437s
SSL: 0.057949s
TTFB: 0.058804s
Total: 0.058896s
问题解决
折腾了几天,随求助于 D 指导,用strace手忙脚乱分析一通,D 指导忽然发散思维,指出 /etc/resolv.conf 可能存在问题。
遂翻阅 resolv.conf 送呈 D 指导:
root@test-shell:/# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local openstacklocal
nameserver 10.96.0.10
options ndots:5
D 指导的原话是:
实际发生的查询顺序是:
- 先查 tailscale-proxy.default.svc.cluster.local.default.svc.cluster.local(拼接第一个 search 域)—— 失败(NXDOMAIN)
- 再查 tailscale-proxy.default.svc.cluster.local.svc.cluster.local —— 失败
- 再查 tailscale-proxy.default.svc.cluster.local.cluster.local —— 失败
- 再查 tailscale-proxy.default.svc.cluster.local.openstacklocal —— 失败
- 最后才查 tailscale-proxy.default.svc.cluster.local.(不加任何后缀的原始域名)—— 成功!
虽然 DNS 服务器对每次失败查询都很快(约 1ms),但连续进行 4~5 轮查询的累积耗时(网络往返 + 客户端处理),就构成了您看到的 20~25ms。
root@test-shell:/# curl -x socks5://tailscale-proxy.default.svc.cluster.local.:1055 -k -s -w "DNS: %{time_namelookup}s
TCP: %{time_connect}s
SSL: %{time_appconnect}s
TTFB: %{time_starttransfer}s
Total: %{time_total}s
" https://k8sbc.default.svc.cross-test-1.remote
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-59689497fb-9486x | v=1
DNS: 0.001073s
TCP: 0.001269s
SSL: 0.043280s
TTFB: 0.069365s
Total: 0.069472s
root@test-shell:/# curl -x socks5://tailscale-proxy:1055 -k -s -w "DNS: %{time_namelookup}s
TCP: %{time_connect}s
SSL: %{time_appconnect}s
TTFB: %{time_starttransfer}s
Total: %{time_total}s
" https://k8sbc.default.svc.cross-test-1.remote
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-59689497fb-9486x | v=1
DNS: 0.000956s
TCP: 0.001134s
SSL: 0.030923s
TTFB: 0.031935s
Total: 0.032013s
颇为难绷,不曾想有一日竟然被 resolv.conf 击落,随发 blog 纪念。
主要是之前测试的时候同样是用 debian:12 的镜像,也没见有 1ms 以上的 DNS 开销。谁能往 resolv.conf 上想!
与 D 指导(DeepSeek)的聊天记录:https://chat.deepseek.com/share/9q9n5c9dmh29syi2sd
btw,我们测试的时候还发现 alpine-bash-curl:latest 这个镜像的 curl 访问同一个域名的延迟上天,SSL 延迟拉爆了(3.28s)。不清楚什么情况。
test-shell-alpine:/# curl -x socks5://tailscale-proxy:1055 -k -s -w "DNS: %{time_namelookup}s
TCP: %{time_connect}s
SSL: %{time_appconnect}s
TTFB: %{time_starttransfer}s
Total: %{time_total}s
" https://k8sbc.default.svc.cross-test-1.remote
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-59689497fb-9486x | v=1
DNS: 0.000822s
TCP: 0.000987s
SSL: 4.008348s
TTFB: 4.009349s
Total: 4.009426s
估计是 alpine 的 curl 有什么编译选项没开。
总之网络测试还得是用 Debian 这种老牌发行版的镜像比较好。
总之就是颇为难绷。
20260709 22:13 Update:
寺貍: 07-09 22:05:39
应该能看到文章了
repere mobile: 07-09 22:05:53
我读完了
寺貍: 07-09 22:06:04
()
寺貍: 07-09 22:06:09
写得很烂这块
repere mobile: 07-09 22:06:53
ndots 5 简直了
repere mobile: 07-09 22:07:26
另外那个 alpine-bash-curl 的 4s lat
repere mobile: 07-09 22:07:40
你知道是怎么回事吗
repere mobile: 07-09 22:07:42
我知道
repere mobile: 07-09 22:09:02
是这样的,虽然初始DNS解析会很快,但是在Socket5 代里协商或者SSL握手的时候
repere mobile: 07-09 22:09:41
Alpine 的 curl 可能会试着进行反向解析,并且强行并发发起IPv4和IPv6 的请求
寺貍: 07-09 22:09:52
什么鬼
repere mobile: 07-09 22:10:11
musl libc 历史上有个很傻逼的行为,就是会把 A 记录和AAAA 记录发到同一个 socket
repere mobile: 07-09 22:10:51
如果对 v6 的处理不当就会死等到 tls
repere mobile: 07-09 22:11:03
这个时间就是 2s 或者 4s
寺貍: 07-09 22:11:35
那真他妈有够傻逼的
repere mobile: 07-09 22:11:45
或者检查里的那个镜像有没有随机数生成的守护进程,因为因为 Alpine 默认是绑定LibreSSL或者mbedatLS 的
repere mobile: 07-09 22:11:54
因为没有 haveged
寺貍: 07-09 22:12:19
我要把你的发言记录下来然后附到这篇blog里
寺貍: 07-09 22:12:24
警钟敲烂
repere mobile: 07-09 22:12:25
必 须 收 集 足 够 的 系 统 熵
repere mobile: 07-09 22:12:57
建议 NodeLocal DNSCache
repere mobile: 07-09 22:13:27
这个坑坑了我小半年
寺貍: 07-09 22:14:16
()
repere mobile: 07-09 22:14:27
如果你的这个 curl 足够稳定掉 4s
repere mobile: 07-09 22:14:39
那很可能就是 IPv6 的问题
寺貍: 07-09 22:14:39
那我应该去怀疑musl,是吧
repere mobile: 07-09 22:14:57
对
总之,如果基于 musl c 的发行版上的 curl 稳定掉 4s 的延迟,那么请怀疑 v6 的连通性。