近日研发测试发布任务全线延迟和失败,导致运维同学排错很久,最后定位到网络问题,反馈到我这边后,我迅速检查内部机房网络和整个内网情况,监控告警是没有任何信息,而排查对应的k8s work节点,抽检几台work节点做网络问题排查,最后竟然是DNS问题,这个问题我觉得应该值得记录下来,下面介绍下问题发现和排障过程。
接到线上运维同学反馈,测试环境下发布任务全部失败,研发的测试发布都卡在某个节点,导致最后超时失败,但是也不是全部失败,大部分失败,初步排查,怀疑是网络问题,故我马上跟进排查。
网络排查
抽检几台k8s的节点,上去查看宿主机网络,和节点网络,通过ping测试,路由追踪发现网络并没有明显故障,查看延迟和内网路由,以及公网路由都是正常的状态。
带宽瓶颈
既然内网无问题,测试内网路由和ping测试都是正常,而公网测试也是正常,怕带宽瓶颈问题影响,故不放心,去看了下出口带宽监控数据和出口AD设备监控,发现并没有带宽瓶颈问题。
在此刻,我们被卡住很久,到底什么问题呢,测试环境如火如荼,都在等着发布,感觉到这一刻好像还是没有头绪时候,有个小伙伴说curl网站响应很慢,想到有几个可能,防火墙、ipv6、以及DNS相关,排查服务器防火墙无问题,ipv6未启用,遂大致可以确定是DNS问题。
DNS排查
在服务器上,curl模拟http请求,如:
$ curl cip.cc | more
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 201 0 201 0 0 36 0 --:--:-- 0:00:05 --:--:-- 49
IP : 122.xxx.174.xxx
地址 : 中国 浙江 杭州
运营商 : 电信
数据二 : 浙江省杭州市 | 电信
数据三 : 中国浙江省杭州市 | 电信
URL : http://www.cip.cc/122.xxx.174.xxx
肉眼观看确实数据响应很慢,但是为了确定到底是那个环节慢,故我需要统计每个解决花费的时间,特别是DNS请求阶段、TCP连接阶段、数据传输阶段等数据,确定那个环节导致的很慢。curl请求过程图::(盗图
故继续使用curl模拟http请求,并使用变量输出对于阶段花费的时间,如下所示:
$ time curl https://www.baidu.com
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus=autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn" autofocus></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=https://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script1>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');
</script1> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必读</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a> 京ICP证030173号 <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
real 0m16.284s
user 0m0.072s
sys 0m0.036s
使用time命令,可以看到curl实际运行时间在16.284s,这个时间是无法接受的,而且严重不正常的现象,故继续使用curl命令分析请求的耗时时间。
$ curl -o /dev/null -s -w %{time_namelookup}---%{time_connect}---%{time_starttransfer}---%{time_total}---%{speed_download}"n" www.baidu.com
15.513---15.532---15.559---15.560---362.000
可以看出curl在time_namelookup阶段花费的时间最长。
curl参数说明:使用-w的参数打印信息。
它能够按照指定的格式打印某些信息,里面可以使用某些特定的变量,而且支持 n、t和 r 转义字符。提供的变量很多,比如 status_code、local_port、size_download 等等,这篇文章我们只关注和请求时间有关的变量(以 time_ 开头的变量)。
新建文本:curl-format.txt 文本
time_namelookup: %{time_namelookup}n
time_connect: %{time_connect}n
time_appconnect: %{time_appconnect}n
time_redirect: %{time_redirect}n
time_pretransfer: %{time_pretransfer}n
time_starttransfer: %{time_starttransfer}n
----------n
time_total: %{time_total}n
变量含义说明:
time_namelookup:DNS 域名解析的时候,就是把 https://zhihu.com 转换成 ip 地址的过程
time_connect:TCP 连接建立的时间,就是三次握手的时间
time_appconnect:SSL/SSH 等上层协议建立连接的时间,比如 connect/handshake 的时间
time_redirect:从开始到最后一个请求事务的时间
time_pretransfer:从请求开始到响应开始传输的时间
time_starttransfer:从请求开始到第一个字节将要传输的时间
time_total:这次请求花费的全部时间
先来看下http相关的简单请求,没有SSL和重定向:
$ curl -w "@curl-format.txt" -o /dev/null -s -L "http://cizixs.com"
time_namelookup: 0.012
time_connect: 0.227
time_appconnect: 0.000
time_redirect: 0.000
time_pretransfer: 0.227
time_starttransfer: 0.443
----------
time_total: 0.867# 可以看到这次请求各个步骤的时间都打印出来了
# 每个数字的单位都是秒(seconds)
# 这样可以分析哪一步比较耗时,方便定位问题
这个命令各个参数的意义:
-w:从文件中读取要打印信息的格式
-o /dev/null:把响应的内容丢弃,因为我们这里并不关心它,只关心请求的耗时情况
-s:不要打印进度条
从这个输出,我们可以算出各个步骤的时间:
DNS 查询:12ms
TCP 连接时间:pretransfter(227) - namelookup(12) = 215ms
服务器处理时间:starttransfter(443) - pretransfer(227) = 216ms
内容传输时间:total(867) - starttransfer(443) = 424ms
来个比较复杂的,访问某度首页,带有中间有重定向和 SSL 协议:
$ curl -w "@curl-format.txt" -o /dev/null -s -L "https://baidu.com"
time_namelookup: 0.012
time_connect: 0.018
time_appconnect: 0.328
time_redirect: 0.356
time_pretransfer: 0.018
time_starttransfer: 0.027
----------
time_total: 0.384
可以看到 time_appconnect 和 time_redirect 都不是 0 了,其中 SSL 协议处理时间为 328-18=310ms。而且 pretransfer 和 starttransfer 的时间都缩短了,这是重定向之后请求的时间。
通过上面的curl命令,定位到DNS域名解析时间严重不正常,故定位到内部DNS服务器上,首先查看到各节点服务器上 /etc/resolv.conf 文件中使用的DNS服务器是内部LDNS,到LDNS上查看问题。
bind 9服务器排查
内部LDNS使用了bing 9和PowerDNS搭建的,两台递归服务器加负载均衡器dnsdist,而查看测试环境的DNS配置只有其中一台bind 9的服务器地址,故服务器DNS需要再添加个内部LDNS,估计是当初的镜像没有只配置了一个DNS,需要修改系统镜像。但这台bind 9搭建的递归服务器有啥问题呢,查看DNS服务端关键日志:
no more recursive clients (1000/0/1000): quota reached
no more recursive clients (1000/0/1000): quota reached
no more recursive clients (1000/0/1000): quota reached
日志中显示该错误,执行 rndc status 发现 recursive clients 一直维持在 1000/0/1000 的状态,查询官方文档参数,发现这是允许递归查询的客户端并发数,官方默认是1000,而现在并发打满,故需要调大递归查询的并发数。
打开bind 9配置文件找到 options ,添加参数:
# 添加并发数到10000
recursive-clients 10000;
重启服务器:rndc restart
业务方发现马上发布服务正常,一切都是DNS惹的祸。
后续改进:
DNS添加两个
DNS服务器关键参数做好监控报警
好了这就是这次DNS的问题排查过程,由于影响时间比较长,大概40分钟,故记录下本次故障排查过程。
服务热线
1391-024-6332
Copyright 2015-2018 www.intsavi.com.cn All Rights Reserved
电话:010-62980070 010-62961051 手机:13910246332
版权所有北京赛维博信科技发展有限公司 备案号:京ICP备14043711号-1 京ICP备14043711号-3