记一次域名解析的问题定位

1 问题现象

我们的程序属于客户端程序,该程序运行在容器中,进程启动后会调用服务端接口获取配置信息,在测试环境一直都没有问题,但是更新到线上环境后就出现问题,调用服务端接口报错,错误信息是执行HTTP请求失败,错误码为7。

2 定位过程

  • 确定是必现问题还是偶现:进程调用配置接口失败,会自动重启,重启后依然出现该报错信息,说明是必现的。
  • 确定是程序问题还是环境问题:同一个服务端,其他集群上都没有问题,只有这一个OpenShift集群出现问题,初步怀疑是环境问题
  • 根据错误信息判断大致的问题:程序使用的是libcurl库连接服务端,在libcurl的帮助文档上查看到错误码为7的含义为:Failed to connect() to host or proxy,说明无法连接到目标机器
  • 在内部用该OpenShift集群安装其他环境的客户端程序自测:运行正常,与出现问题的场景的区别是内部自测时没有配置域名,客户端是直接通过IP连接,而线上环境配置了域名
  • 复现:内部找了个服务端配置了域名的环境测试,在该OpenShift集群确实可以复现,然后安装了debug版本的程序,查看到详细的HTTP调用日志,发现IP解析的不对,确认是域名解析的问题
  • 进入到容器中,使用curl和ping可以解析到正确的IP地址

3 域名解析中的/etc/resolv.conf

程序解析域名时会读取/etc/resolv.conf,其中主要有两个字段:

  • ndots:域名中点的个数限制
  • search:主域名
  • nameserver:域名服务器的地址

如果要访问的域名不以点号结尾,且点号的个数小于ndots,则将要访问的域名依次跟search中的主域名拼接,然后再向nameserver配置的域名服务器查询,否则,直接向nameserver发起域名查询请求。

执行strace ping发现,域名查询时会尝试search中的多个域名,但是都失败了,最后会尝试不带域名的形式,从而找到正确的IP地址,而对我们的程序执行strace时,发现在尝试search中的最后一个域名时成功了,返回了OpenShift集群的引导节点的IP。

在宿主机上用任何字符串后面接search中的最后一个主域名进行ping,发现都会返回引导节点的IP地址,这个跟我们的现象很像,而且宿主机的nameserver配置的也是引导节点。

登录OpenShift的引导节点,发现上面有CoreDNS,且其中有个配置:

template IN A hello.cn {
    match .*hello\.cn # 匹配请求 DNS 名称的正则表达式
    answer "{{ .Name }} 60 IN A 127.0.0.1" # DNS 应答
    fallthrough
}

虽然不太看得懂该配置文件,但是大概可以猜出来,该配置会导致任何以hello.cn结尾的域名都返回下面的127.0.0.1。

4 遗留问题

基本确定就是上述配置导致我们的程序无法解析到正确的服务端IP,从而导致无法连接,唯一遗留的问题是:

为什么ping活着curl命令可以解析到正确的IP,而调用libcurl得到的IP却是不对的?

后面有时间再看下。

相关推荐
初晴~17 天前
【网络原理】数据链路层协议与DNS
网络·c++·python·网络协议·以太网·dns·数据链路层
火山引擎边缘云20 天前
亮相QCon2024,火山引擎边缘云揭秘云原生操作系统与HTTPDNS技术实践
云原生·边缘计算·dns
fareast_mzh24 天前
Difference between `systemd-resolved` and `dnsmasq`
运维·dns
CXDNW1 个月前
【网络篇】计算机网络——应用层详述(笔记)
服务器·笔记·计算机网络·http·web·cdn·dns
zhangxueyi1 个月前
详解DNS工作原理及实例分析
linux·运维·服务器·dns
威迪斯特1 个月前
linux网络服务:网络名称解析管理器,提供系统级的DNS缓存服务,并管理网络连接和DNS解析的服务systemd-resolved详解
linux·服务器·网络·缓存·dns·域名解析
中草药z1 个月前
【JavaEE】数据链路层协议和DNS
网络·学习·mac·ip·dns·mtu·数据链路
威迪斯特2 个月前
Linux网络工具:用于查询DNS(域名系统)域名解析信息的命令nslookup详解
linux·运维·服务器·centos·域名解析·域名系统·反向解析
青衫客362 个月前
DNS解析流程
计算机网络·dns