容器里域名解析慢半拍:ndots、search 域与 conntrack 表满的三层排查

举报
yd_291384559 发表于 2026/11/08 15:43:06 2026/11/08
【摘要】 容器里域名解析偶发 5 秒延迟,多数不是 DNS 服务器故障。本文按 ndots 放大查询次数、glibc 超时参数与解析地址错配、conntrack 表满丢弃 UDP 包三层排查,给出 dig、tcpdump、dmesg 与 conntrack 的验证命令和处置顺序。

同一个容器里,ping 一个 IP 秒回,curl 一个域名却偶发 5 秒左右才响应,重试又恢复正常。这类「慢半拍」的问题十有八九卡在 DNS,而且多数不是 DNS 服务器本身故障。下面按三层由易到难排查:查询次数被放大、解析器超时被吃满、UDP 53 的包被内核丢掉。

一、先确认慢在哪一步

不要在应用日志里猜,先把解析这一跳单独测出来:

# 看解析耗时(不经过应用)
time getent hosts api.example.com

# 看实际发出去了哪些查询
tcpdump -ni any -c 20 port 53

如果 getent hosts 也慢,问题就在解析链路;如果只有应用慢,先怀疑应用自己的连接池或重试逻辑。这一步能把范围砍掉一半。

二、ndots 把一次查询放大成五六次

容器里的 /etc/resolv.conf 常见两行:

search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

ndots:5 的含义是:域名字面里的点数少于 5 个时,先把每个 search 域拼上去试一遍,最后才按绝对域名查。api.example.com 只有 2 个点,解析器实际会依次查:

api.example.com.default.svc.cluster.local
api.example.com.svc.cluster.local
api.example.com.cluster.local
api.example.com

前三次注定 NXDOMAIN,却都要走一趟网络。集群 DNS 一旦有几十毫秒抖动,放大五六倍就是肉眼可见的卡顿。验证方法:

dig +search api.example.com   # 能看到按 search 列表逐个查询
dig api.example.com.          # 末尾加点 = 绝对域名,跳过 search

三个不改架构的修法:

  • 调用外部域名时写带尾点的 FQDN(api.example.com.),直接跳过 search 列表;
  • 把 ndots 调到 2 左右,Kubernetes 下可用 dnsConfig.options 覆盖;
  • 部署 NodeLocal DNSCache,把解析收敛到节点本地,减少一次跨节点往返。

三、一次丢包就是一次 5 秒

glibc 解析器默认 timeout:5、attempts:2。DNS 主要走 UDP,而 UDP 没有重传,包一丢,客户端只能干等 5 秒再发第二次。所以「偶发 5 秒」几乎就是一次丢包的指纹。查两处:

cat /etc/resolv.conf                # 有没有写 timeout / attempts
systemctl status systemd-resolved   # 宿主机是否启用了 127.0.0.53 stub

一个常见误区:宿主机把 127.0.0.53 写进 resolv.conf,容器又整份复制过去。容器有自己的网络命名空间,127.0.0.53 指向容器自己而不是宿主机的 systemd-resolved,结果是连不上、只能等超时。容器里的解析地址应当是集群 DNS 的 Service IP 或节点地址。

四、conntrack 表满,UDP 包被静默丢弃

前两层都正常却仍然偶发超时,就要看内核有没有在丢包:

dmesg -T | grep -i nf_conntrack
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
conntrack -C

看到 nf_conntrack: table full, dropping packet 就实锤了:连接跟踪表满了,新包直接丢,DNS 的 UDP 查询首当其冲。表里堆积的多是大量短命 UDP 条目,默认 nf_conntrack_udp_timeout 为 30 秒,高并发下很快填满。处置顺序:

  1. 先把 nf_conntrack_max 调大,同时关注 nf_conntrack_buckets;
  2. 把 nf_conntrack_udp_timeout 适当调小,让条目更快回收;
  3. 让 DNS 流量在 raw 表走 NOTRACK,从根上不占 conntrack;
  4. 长期方案仍是 NodeLocal DNSCache,把查询压在节点内。

五、排查顺序小结

先量解析耗时锁定 DNS,再用 dig +search 判断查询次数是否被放大,然后核对 resolv.conf 的超时参数与解析地址,最后用 dmesg 和 conntrack 计数确认内核是否在丢包。不要一上来就改 /etc/hosts,它只会把问题藏起来,换个域名照样复发;也别把 5 秒延迟记到应用性能账上,那正好是一个解析超时周期的量级。

一句话记住:DNS 慢,多数时候不是「解析不出来」,而是「问得太多」或者「问了没人答」。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。