探讨在linux环境下的dns客户端配置 /etc/resov.conf配置的options rotate对nameserver中解析行为的影响以及常遇到的几个相关问题。
1. 配置作用说明
通过执行命令man resolv.conf
查看rotate的说明
rotate sets RES_ROTATE in _res.options, which causes round-robin selection of nameservers from among those listed. This has the effect of spreading the query load among all listed servers, rather than having all clients try the first listed server first every time.
翻译成中文
rotate 在_res中设置RES_ROTATE的选项,
它导致从列出的nameserver中进行轮询选择,这样可以在所有列出的服务器之间分散查询负载,而不是让所有客户端每次都先尝试第一个列出的服务器。
因此配置options rotate
前后的业务行为表现差异如下
-
不配置
options rotate
,客户端程序如果尝试解析多个域名,每个域名解析时都是从第1个nameserver进行解析,如果解析超时(不包括解析正常但是没有相关的解析记录),则会选择下一个nameserver进行解析,直到解析成功(包括解析正常但是没有相关的解析记录)或者nameserver列表全部尝试完。这样会导致所有的解析压力都集中在第一个nameserver。 -
配置
options rotate
,客户端程序如果尝试解析多个域名,每个域名解析时是从nameserver列表中使用轮询的方式选择对应的nameserver进行解析(通常会从第二个nameserver开始解析,后面会解释为什么会选择第二个),从而缓解将解析压力缓解分散到多个nameserver上。如果多个nameserver的解析行为不一致,会导致每次域名解析的结果有差异。
具体的配置使用,请根据实际情况进行调整和配置。
2. 测试过程以及相关说明
配置/etc/resolv.conf的配置,并将测试过程分为2个阶段
cat /etc/resolv.conf
# 根据实际情况调整
# options timeout:1 attempts:1 rotate
# 异常nameserver,解析超时
nameserver 10.33.0.115
# 正常nameserver,能够正常解析
nameserver 192.168.192.10
# 正常nameserver,但是不能解析测试域名
nameserver 10.33.0.11
分别准备2个测试脚本,
# 测试脚本resolv.sh
for i in {1..10};do dig xx.xx.com.cn;done
# 测试脚本resolv.py
import socket
for x in range(10):
try:
print socket.getaddrinfo('xx.xx.com.cn', 80);
except:
pass
之所以使用2个测试脚本,主要是为了避免由于不同语言导致的调用底层库不一致,从而导致行为差异。
2.1. 不配置options rotate验证解析过程
不配置options rotate
,预期是顺序解析,解析请求只发送给第一个nameserver
- 如果第一个namserver解析成功(包括解析正常但是没有相关的解析记录),则不会向后续的nameserver进行解析申请
- 如果第一个namserver解析超时(不包括解析正常但是没有相关的解析记录),则会选择下一个nameserver进行解析,直到解析成功(包括解析正常但是没有相关的解析记录)或者nameserver列表全部尝试完
2.1.1 第一个nameserver能够正常解析
相关配置
cat /etc/resolv.conf
# 根据实际情况调整
# options timeout:1 attempts:1 rotate
# 正常nameserver,能够正常解析
nameserver 192.168.192.10
# 异常nameserver,解析超时
nameserver xx.xx.xx.xx
# 正常nameserver,但是不能解析测试域名
nameserver xx.xx.xx.xx
执行解析过程如下
# 使用reslov.sh进行测试
strace -e trace=connect,write sh resolv.sh
# 使用reslov.py进行测试
strace -e trace=connect,write python resolv.py
结论:如果第一个namserver解析成功(包括解析正常但是没有相关的解析记录)时,所有的解析请求只会发送到第一个nameserver进行解析。
2.1.2 第一个nameserver解析超时
相关配置
cat /etc/resolv.conf
# 根据实际情况调整
# options timeout:1 attempts:1 rotate
# 异常nameserver,解析超时
nameserver xx.xx.xx.xx
# 正常nameserver,能够正常解析
nameserver 192.168.192.10
# 正常nameserver,但是不能解析测试域名
nameserver xx.xx.xx.xx
执行解析过程如下
# 使用reslov.sh进行测试
strace -e trace=connect,write sh resolv.sh
# 使用reslov.py进行测试
strace -e trace=connect,write python resolv.py
结论:如果第一个namserver解析超时(不包括解析正常但是没有相关的解析记录),则会选择下一个nameserver进行解析,直到解析成功(包括解析正常但是没有相关的解析记录)或者nameserver列表全部尝试完。
2.2. 配置options rotate验证解析过程
2.2.1 第二个nameserver能够正常解析
在测试用例里面,特地将第二个nameserver配置成正常解析(第二个序号比较特殊,有代表意义),验证整体的解析过程
相关配置
cat /etc/resolv.conf
# 根据实际情况调整
options timeout:1 attempts:1 rotate
# 异常nameserver,解析超时
nameserver xx.xx.xx.xx
# 正常nameserver,能够正常解析
nameserver 192.168.192.10
# 正常nameserver,但是不能解析测试域名
nameserver xx.xx.xx.xx
执行解析过程如下
# 使用reslov.sh进行测试
strace -e trace=connect,write sh resolv.sh
# 使用reslov.py进行测试
strace -e trace=connect,write python resolv.py
结论:
1,能够达到轮询的效果,多个nameserver轮询的访问,大概率会选中第二个nameserver作为第一个解析节点
2,如果第一次获取nameserver解析超时,会按照顺序继续进行选择第二个nameserver进行解析,知道完成所有节点轮询为止。
3,shell脚本进行解析的模式跟python不一致,shell脚本每次都是选择第二个nameserver进行解析,而py则从第二个nameserver开始进行轮询。10次shell解析全部成功,但是py只有6次
只有6次解析成功,原因分析如下,使用py进行解析时:
3次选中第一个nameserver,解析超时,会继续选择第二个nameserver进行解析,解析成功
3次选中第二个nameserver,解析成功
4次选中第三个nameserver,解析成功,但是没有解析结果
事实上如果按照如下方式配置/etc/resolv.conf,使用py进行解析时,10次解析都是成功的
cat /etc/resolv.conf
# 根据实际情况调整
options timeout:1 attempts:1 rotate
# 异常nameserver,解析超时
nameserver xx.xx.xx.xx
# 正常nameserver,能够正常解析
nameserver 192.168.192.10
# 异常nameserver,解析超时
nameserver xx.xx.xx.xx
其中的一个解析过程如下,会在列表中自动选择下一个nameserver进行解析。
2.2.2 第二个nameserver解析超时
相关配置
cat /etc/resolv.conf
# 根据实际情况调整
options timeout:1 attempts:1 rotate
# 正常nameserver,能够正常解析
nameserver 192.168.192.10
# 异常nameserver,解析超时
nameserver xx.xx.xx.xx
# 正常nameserver,但是不能解析测试域名
nameserver xx.xx.xx.xx
执行解析过程如下
# 使用reslov.sh进行测试
strace -e trace=connect,write sh resolv.sh
# 使用reslov.py进行测试
strace -e trace=connect,write python resolv.py
结论跟2.2.1 的表现一致,说明确实起到了不同的nameserver轮询的效果。
3. 疑问和思考
3.1 配置了rotate为什么优先使用第二个nameserver进行解析?
重新排序后位置发生了变化,GLIBC库的函数将第二位的IP移动到了第一位
__libc_res_nsend:
if (__builtin_expect ((statp->options & RES_ROTATE) != 0, 0) &&
(statp->options & RES_BLAST) == 0) {
struct sockaddr_in6 *ina;
unsigned int map;
n = 0;
while (n < MAXNS && EXT(statp).nsmap[n] == MAXNS)
n++;
if (n < MAXNS) {
ina = EXT(statp).nsaddrs[n];
map = EXT(statp).nsmap[n];
for (;;) {
ns = n + 1;
while (ns < MAXNS
&& EXT(statp).nsmap[ns] == MAXNS)
ns++;
if (ns == MAXNS)
break;
EXT(statp).nsaddrs[n] = EXT(statp).nsaddrs[ns]; -----------> 把第二个IP地址移动到第一个
EXT(statp).nsmap[n] = EXT(statp).nsmap[ns];
n = ns;
}
EXT(statp).nsaddrs[n] = ina;
EXT(statp).nsmap[n] = map;
从整个代码逻辑中可以发现
如果配置rotate轮询选项,__libc_res_nsend会首先使用第二位的IP地址(这一点上不知道为什么这样设计,不知道什么原因导致这样的设计)。
该问题已经在RedHat官网上有了说明
Why option rotate in resolv.conf picks up second nameserver as first every time?
3.2 为什么nameserver配置只有前3个有效?
默认情况下/etc/resolv.conf 只能配置三个,多nameserver配置查询不到 因为MAXNS
被定义三个,可以修改重新编译,但官方不推荐
man resolv.conf
可以在这里获取相关的源码resolv.h或者在服务器上执行
vim /usr/include/resolv.h
3.3 问题拓展:nameserver解析不了主机时,不能故障转移:
这个问题大多出现在/etc/resov.conf 中配置了多个nameserver,但是不同的nameserver的解析能力不一致情况。
例如 域名a.com只能在10.0.0.2中解析,但是10.0.0.2中的相关解析记录被删除,就会导致对应的域名会一直都无法解析,不能自恢复。文章来源:https://www.toymoban.com/news/detail-810856.html
nameserver 10.0.0.1 # handles queries for some internal zones
nameserver 10.0.0.2 # handles queries for zones that .1 nameserver doesn't know about
nameserver 10.0.0.3 # handles queries out to the global internet
是因为,配置options rotate
,客户端程序如果尝试解析多个域名,每个域名解析时是从nameserver列表中使用轮询的方式选择对应的nameserver进行解析(通常会从第二个nameserver开始解析,后面会解释为什么会选择第二个),如果nameserver能够响应(但是没有相关的解析记录),并不判断为解析超时,自然不会继续切换下一个nameserver文章来源地址https://www.toymoban.com/news/detail-810856.html
4. 参考文档
- 偶尔解析失败,resolv.conf配置rotate问题
- Why option rotate in resolv.conf picks up second nameserver as first every time?
- Linux上DNS解析总是选择resolv.conf中第二位的DNS服务器IP地址
到了这里,关于Liunx的/etc/resov.conf配置的options rotate对nameserver行为的影响的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!