dnsredir icon indicating copy to clipboard operation
dnsredir copied to clipboard

出现大量告警Read UDP错误,i/o超时

Open Dodotry opened this issue 2 years ago • 34 comments

基于coredns源代码,添加dnsredir插件编译后,出现较多的i/o timeout,主机上已对内核的相关TCP参数优化,好像没有改善,有遇到这问题的吗?有什么方式能优化调整?

[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 7.7.22.2:53924->119.29.29.29:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 172.31.180.141:34824->202.130.97.65:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 7.7.22.2:49496->223.5.5.5:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 172.31.180.141:59482->202.130.97.65:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 172.31.180.141:39944->202.130.97.65:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 172.31.180.141:60629->8.8.8.8:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 172.31.180.141:49605->202.130.97.65:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 7.7.22.2:59442->114.114.114.114:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 7.7.22.2:49845->223.5.5.5:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 172.31.180.141:38189->1.1.1.1:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 172.31.180.141:42711->1.1.1.1:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 172.31.180.141:39886->202.130.97.65:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 7.7.22.2:46461->114.114.114.114:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 172.31.180.141:46362->202.130.97.65:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 7.7.22.2:55348->114.114.114.114:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 7.7.22.2:49217->114.114.114.114:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 172.31.180.141:52597->1.1.1.1:53: i/o timeout
[WARNING] plugin/dnsredir: Exchange() failed  error: read udp 7.7.22.2:58954->114.114.114.114:53: i/o timeout

Dodotry avatar Oct 11 '21 09:10 Dodotry

用coredns官方的forward插件配置同样的上游DNS先验证下看看是不是能复现这个问题?

如果能,说明是网络的确有问题,比如丢包率很高,你可以尝试在高峰时期 ping 114.114.114.114 之类的看看丢包率。

我看你用的是UDP协议(原始DNS),可以把协议换成TCP协议,TCP协议在国内的ToS一般高于UDP,高峰时期也许有用。

另外这些常见的DNS地址全部io timeout,我怀疑是不是你的VPS宿主机层面禁用了UDP协议?

可以用 dig @223.5.5.5 baidu.com 试试看能不能正常响应。

dig @223.5.5.5 +tcp baidu.com (对应的TCP请求)

leiless avatar Oct 12 '21 00:10 leiless

用coredns官方的forward插件配置同样的上游DNS先验证下看看是不是能复现这个问题?

如果能,说明是网络的确有问题,比如丢包率很高,你可以尝试在高峰时期 ping 114.114.114.114 之类的看看丢包率。

我看你用的是UDP协议(原始DNS),可以把协议换成TCP协议,TCP协议在国内的ToS一般高于UDP,高峰时期也许有用。

另外这些常见的DNS地址全部io timeout,我怀疑是不是你的VPS宿主机层面禁用了UDP协议?

可以用 dig @223.5.5.5 baidu.com 试试看能不能正常响应。

dig @223.5.5.5 +tcp baidu.com (对应的TCP请求)

十分感谢回复,日志里面我没有开启正常响应的日志,只记录了告警类。ping常见的公共DNS延时正常没有丢包,我尝试使用TCP协议后,统计少了一些timeout,但国外公共DNS没有明显变化。 VPS上没有禁用UDP,告警是有一定的比例存在。

Dodotry avatar Oct 12 '21 04:10 Dodotry

统计少了一些timeout,但国外公共DNS没有明显变化

如果你的是在国内的云服务器上请求国外的IP的话,应该会很容易导致丢包的(国情),即便TCP也是如此。 我猜测你用coredns官方forward插件请求国外公共DNS也会产生类似的情况,有条件的话你可以验证下看看。

需要你确认下:

  • 请求国内公共DNS io timeout是不是会明显减少很多?
  • 请求国外公共DNS io timeout是不是会明显增加很多?

leiless avatar Oct 12 '21 05:10 leiless

如果你的是在国内的云服务器上请求国外的IP的话,应该会很容易导致丢包的(国情),即便TCP也是如此。 我猜测你用coredns官方forward插件请求国外公共DNS也会产生类似的情况,有条件的话你可以验证下看看。

VPS使用境外IP,并有GRE到国内节点上,路由将国内公共DNS指向GRE。用forward会有timeout情况,但很少,不常现。

需要你确认下:

  • 请求国内公共DNS io timeout是不是会明显减少很多?

国内有明显减少

  • 请求国外公共DNS io timeout是不是会明显增加很多?

不会明显增加,只有1.1.1.1会相对较多超时。

Dodotry avatar Oct 13 '21 02:10 Dodotry

VPS使用境外IP,并有GRE到国内节点上,路由将国内公共DNS指向GRE。用forward会有timeout情况,但很少,不常现。

看起来拓扑结构是: End-user request <-> VPS(海外) coredns <-> 分流请求Public DNS(国内/国外)

你的意思是VPS coredns-dnsredir <-> Public DNS经常出现io timeout,但是同样的配置换成coredns-forward之后io timeout会减少很多对吗?

另外,GRE是什么东西?

leiless avatar Oct 13 '21 03:10 leiless

VPS使用境外IP,并有GRE到国内节点上,路由将国内公共DNS指向GRE。用forward会有timeout情况,但很少,不常现。

看起来拓扑结构是: End-user request <-> VPS(海外) coredns <-> 分流请求Public DNS(国内/国外)

你的意思是VPS coredns-dnsredir <-> Public DNS经常出现io timeout,但是同样的配置换成coredns-forward之后io timeout会减少很多对吗?

对的。

另外,GRE是什么东西?

VPS → CN Node创建了GRE隧道 到国内DNS走7.7.22.1/30

image

Dodotry avatar Oct 13 '21 04:10 Dodotry

可以分别贴一下 coredns-dnsredir 和 coredns-forward的配置吗?

从第一条评论的日志来看,是海外VPS DNS回溯国内公共DNS(通过GRE隧道到CN node)查询的时候出现了UDP read timeout。

我怀疑可能是GFW动了一些手脚,因为常规的DNS (UDP + TCP)请求都是明文的。

leiless avatar Oct 13 '21 05:10 leiless

可以分别贴一下 coredns-dnsredir 和 coredns-forward的配置吗?

从第一条评论的日志来看,是海外VPS DNS回溯国内公共DNS(通过GRE隧道到CN node)查询的时候出现了UDP read timeout。

我怀疑可能是GFW动了一些手脚,因为常规的DNS (UDP + TCP)请求都是明文的。

当前的配置是这样的,forward配置的时候没有走分流解析,简单的试了一下海外和国内各两个。没敢多试,有用户体验不好。


.:53  {
  errors
  hosts {
    fallthrough
  }
  forward . 127.0.0.1:5302
  health :28080
  # prometheus :9153
  # log . "{type}|{proto}|{remote}:{port} - {>id},{size},{>do},{>bufsize},{rcode},{rsize},{duration},{name}"
  lrucache 50000
  template ANY AAAA {
      rcode NXDOMAIN
  }
  reload 30s
}

.:5302 {
  bind 127.0.0.1
  dnsredir /opt/coredns/conf/mydns.conf {
      expire 15s
      max_fails 3
      health_check 5s
      policy random
      path_reload 10s
      to 114.114.114.114
      to 202.96.128.86
  }
  dnsredir /opt/coredns/conf/overseas.conf {
      expire 15s
      max_fails 3
      health_check 5s
      policy round_robin
      path_reload 10s
      to 208.67.222.222
  }
  dnsredir /opt/coredns/conf/accelerated-domains.china.conf /opt/coredns/conf/apple.china.conf {
      expire 15s
      max_fails 3
      health_check 5s
      policy round_robin
      path_reload 10s
      to tcp://119.29.29.29
      to 114.114.114.114 tcp://223.5.5.5
  }
  dnsredir . {
      expire 60s
      max_fails 5
      health_check 5s
      policy random
      spray
      to tcp://202.130.97.65
      to tls://[email protected] tls://[email protected]
      to 1.1.1.1 tls://9.9.9.9
  }
  # log . "{type}|{proto}|{remote}:{port} - {>id},{size},{>do},{>bufsize},{rcode},{rsize},{duration},{name}"
  loop
  reload 30s

Dodotry avatar Oct 13 '21 06:10 Dodotry

我怀疑可能是GFW动了一些手脚,因为常规的DNS (UDP + TCP)请求都是明文的。

不排除这种可能。

Dodotry avatar Oct 13 '21 06:10 Dodotry

当前的配置是这样的,forward配置的时候没有走分流解析,简单的试了一下海外和国内各两个。没敢多试,有用户体验不好。

我稍晚一点看,现在忙。

有条件可以再开一组海外VPS + CN node,将GRE将他们连起来,这样环境就一样了,就可以作为测试环境了。

leiless avatar Oct 13 '21 06:10 leiless

没敢多试,有用户体验不好。

另外,如果你有很多用户使用的情况下,也是有可能被GFW盯上的。

当然不排除机器性能跟不上用户请求,导致内核丢包,终端用户看到的就是超时了(UDP)。

leiless avatar Oct 13 '21 06:10 leiless

没敢多试,有用户体验不好。

另外,如果你有很多用户使用的情况下,也是有可能被GFW盯上的。

当然不排除机器性能跟不上用户请求,导致内核丢包,终端用户看到的就是超时了(UDP)。

还是感觉不太正常,看下面的一段配置,forward直接均衡到了202.130.97.65 8.8.8.8,相当于dnsredir已经空闲,而且去掉了健康检查,这一台是另外一台新VPS,几乎没什么访问量,这是什么原因?

image

异常如下: image

Dodotry avatar Oct 14 '21 09:10 Dodotry

迷糊了……

Dodotry avatar Oct 14 '21 09:10 Dodotry

相当于dnsredir已经空闲,而且去掉了健康检查,这一台是另外一台新VPS,几乎没什么访问量,这是什么原因?

注释掉 health_check 相当于使用默认值,你可以设置一下默认值 max_fails 0

max_fails is the maximum number of consecutive health checking failures that are needed before considering an upstream as down. 0 to disable this feature(which the upstream will never be marked as down). Default is 3.

leiless avatar Oct 14 '21 09:10 leiless

另外看起来需要支持一下 health_check 0 去禁用health_check,等有时间我改下..

leiless avatar Oct 14 '21 09:10 leiless

另外看起来需要支持一下 health_check 0 去禁用health_check,等有时间我改下..

我正在抓53端口的报文,空闲等待比较久,想多抓几个数据包供分析。

Dodotry avatar Oct 14 '21 10:10 Dodotry

改为 max_fails 0 之后正常了吗?

leiless avatar Oct 14 '21 10:10 leiless

另外看起来需要支持一下 health_check 0 去禁用health_check,等有时间我改下..

我正在抓53端口的报文,空闲等待比较久,想多抓几个数据包供分析。

改为 max_fails 0 之后正常了吗?

附件是抓的报文,配置max_fails 0过后少了很多,是不是没有完全禁掉?

debugdns.zip

Dodotry avatar Oct 14 '21 10:10 Dodotry

另外看起来需要支持一下 health_check 0 去禁用health_check,等有时间我改下..

哈哈,静候大佬佳音~

Dodotry avatar Oct 14 '21 10:10 Dodotry

配置参数max_fails 0后,错误日志明显降低,总错误一天下来大概5k多条,不过偶尔会出现以下错误:

[WARNING] plugin/dnsredir: tls: failed to send closeNotify alert (but connection was closed anyway): write tcp 172.31.180.141:4425->8.8.4.4:853: write: broken pipe
[WARNING] plugin/dnsredir: hc: DNS tls://9.9.9.9:853 failed  rtt: 2.558025584s err: EOF
[WARNING] plugin/dnsredir: hc: DNS tls://9.9.9.9:853 failed  rtt: 2.832479702s err: EOF

Dodotry avatar Oct 21 '21 06:10 Dodotry

配置参数max_fails 0后,错误日志明显降低,总错误一天下来大概5k多条,不过偶尔会出现以下错误:

[WARNING] plugin/dnsredir: tls: failed to send closeNotify alert (but connection was closed anyway): write tcp 172.31.180.141:4425->8.8.4.4:853: write: broken pipe
[WARNING] plugin/dnsredir: hc: DNS tls://9.9.9.9:853 failed  rtt: 2.558025584s err: EOF
[WARNING] plugin/dnsredir: hc: DNS tls://9.9.9.9:853 failed  rtt: 2.832479702s err: EOF

第一条是正常的网络异常现象,第二和第三条看起来还是调用了health check。 等我这周处理处理一下这个问题。

leiless avatar Oct 21 '21 06:10 leiless

另外看起来需要支持一下 health_check 0 去禁用health_check,等有时间我改下..

这次更新是已经支持health_check 0 配置去禁用health_check了吗?

Dodotry avatar Oct 31 '21 07:10 Dodotry

另外看起来需要支持一下 health_check 0 去禁用health_check,等有时间我改下..

这次更新是已经支持health_check 0 配置去禁用health_check了吗?

还没... 我尽快 最近是修复网络请求未设置超时的bug

leiless avatar Nov 01 '21 09:11 leiless

还没... 我尽快 最近是修复网络请求未设置超时的bug

最近发布的版本只修复已知缺陷吗?health_check 0支持配置么?

Dodotry avatar Jan 08 '22 13:01 Dodotry

还没... 我尽快 最近是修复网络请求未设置超时的bug

最近发布的版本只修复已知缺陷吗?health_check 0支持配置么?

health_check 0 很早的版本就支持了。

leiless avatar Jan 16 '22 05:01 leiless

有规划支持禁用health_check配置么?

Dodotry avatar Nov 13 '22 12:11 Dodotry

这段时间找个空闲时间看看,顺便更新下upstream coredns。:-)

leiless avatar Nov 14 '22 01:11 leiless

最近比较忙,可能还得推迟一段时间了。😔

leiless avatar Dec 25 '22 01:12 leiless

最近比较忙,可能还得推迟一段时间了。😔

羊群满地,注意防护

Dodotry avatar Dec 25 '22 13:12 Dodotry

大佬很久没维护了☺

Dodotry avatar Aug 12 '23 04:08 Dodotry