一次/etc/hosts权限错误导致的es集群错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一次/etc/hosts权限错误导致的es集群错误相关的知识,希望对你有一定的参考价值。

参考技术A 先说一下环境:系统使用的CentOS7.5,elasticsearch版本是5.4.0。一套产品集群包括三个elasticsearch节点构成的集群。
部署了两套测试集群,配置基本类似,elasticsearch配置文件中使用主机名。在某一次测试后,一套集群里的elasticsearch就开始报错,无法提供服务。查看日志发现,elasticsearch一直抛出UnknownHostException异常,所以无法和另外两个节点通信连成集群。根据堆栈信息,这个异常是在解析其它elasticsearch节点域名的时候调用InetAddress.getAllByName()抛出的。
而另外一套集群里类似的配置,它的elasticsearch服务却是很正常的。唯一的不同是,出问题的集群临时配置了DNS服务。
按正常的情况来说,elasticsearch解析域名的方式应该是先从/etc/hosts中获取,获取不到了再查询DNS。elasticsearch服务节点的主机名、IP都有在配置在/etc/hosts中。所以,即使一套集群配置了DNS,另外一套没有,也不应该出现elasticsearch无法解析域名的问题。

为了找到域名解析错误的原因,我决定跟踪一下elasticsearch解析域名的过程,使用的工具是strace。strace命令可以追踪进程的系统调用。
安装过程很简单。

接着是修改elasticsearch的执行脚本,一般路径是/usr/share/elasticsearch/bin/elasticsearch。在这个脚本的最后几行,在exec 后添加strace命令 strace -o /tmp/es.strace.log -f ,如下所示。

-o参数将strace的输出保存到文件/tmp/es.strace.log,-f参数表明追踪进程的所有子进程的系统调用。
两个集群的elasticsearch节点都修改了这个脚本,重启服务后对比查看。对比这个输出文件,终于发现一些端倪。首先,elasticsearch调用的getAllByName()确实首先查看了/etc/hosts文件,但是权限不足无法访问这个文件。
这是有问题的,首先是这个文件应该是可读的,不应该出现权限不足的问题,第二是两个集群都无法访问这个文件,但是为什么一个能解析域名而另外一个不能。
接着往下对比,出问题的elasticsearch进程这时候检查到/etc/resovl.conf文件已经配置,于是向DNS服务器发出了查询。DNS无法解析,于是抛出了UnknownHostException异常。另外一边,没有问题的elasticsearch进程检查到/etc/resovl.conf未配置,这时候做了一个特别的操作,它创建了一个地址族是AF_NETLINK的原始套接字,通过这个套接字查询得到了域名对应的IP地址。我猜测,这可能是访问系统的ARP信息。
既然是DNS的问题,那么把出问题的/etc/resolv.conf中的DNS配置删除呢?重启服务之后,elasticsearch服务依然抛出异常,查看日志发现进程虽然跳过了/etc/resolv.conf,但是它却开始访问了本地的DNS端口53(UDP),可能这是java最后的解析尝试了。恰好,这个节点上部署了rpcbind服务,这个服务恰好就监听了53端口,结果就是依然无法通过DNS解析,java华丽丽的抛出了异常。

问题的根本原因还是/etc/hosts文件不可读,查看这个文件的权限,结果是600,意思就是只能root用户读写了,其它用户没有任何权限,包括读。elasticsearch服务使用的elasticsearch用户,所以当然就会被禁止读取。
经过其它的查找,发现是有一个服务进程会一直更新这个hosts文件,更新的方式是先创建一个临时文件,然后rename成hosts文件,由于临时文件的默认权限是600,所以导致hosts文件的权限最后也是600了。
至此,整个的问题的原因已经清楚。hosts权限的错误,导致elasticsearch通过DNS解析域名,又刚好DNS解析报错,没有通过ARP解析域名。
另外从这个事情中也可以看到java解析域名的套路,先/etc/hosts文件,接着是DNS,先远程的DNS后本地的DNS,最后尝试从本地ARP缓存解析,中间有一个过程抛出异常的时候,解析就会失败。

通过命令获取/etc/hosts文件的权限对应的数字

命令获取/etc/hosts文件的权限对应的数字

第一步 查看文件的权限

[[email protected] ~]# stat /etc/hosts

  File: `/etc/hosts‘

  Size: 158         Blocks:8          IO Block: 4096   regular file

Device: 803h/2051d   Inode: 915740      Links: 2

Access:(0644/-rw-r--r--)  Uid: (    0/   root)   Gid: (    0/   root)

Access: 2017-09-0410:54:49.197752741 +0800

Modify: 2017-08-2321:57:12.148687266 +0800

Change: 2017-08-2321:57:12.149687266 +0800

[[email protected] ~]#

第二步    截取第4

[[email protected] ~]# stat/etc/hosts | sed -n ‘4p‘

Access:(0644/-rw-r--r--)  Uid: (    0/   root)   Gid: (    0/   root)

[[email protected] ~]# stat/etc/hosts | awk"NR==4"

Access:(0644/-rw-r--r--)  Uid: (    0/   root)   Gid: (    0/   root)

[[email protected] ~]#

第三步   进行截取

方法一  反向引用

[[email protected] ~]# stat /etc/hosts|sed -nr ‘4s#^.*\(0(.*)/-.*$#\1#gp‘

644

[[email protected] ~]#

方法二  awk指定分隔符

[[email protected] ~]# stat /etc/hosts|awk -F "[0/]" ‘NR==4{print $2}‘

644

[[email protected] ~]#

方法三  正则表达式

[[email protected] ~]# stat /etc/hosts|awk"NR==4"|egrep"[1-7]{3}" -o

644

[[email protected] ~]#

方法四  正则表达式

[[email protected] ~]# stat /etc/hosts|sed -n ‘4s#[^1-7]# #gp‘

         644                                                           

[[email protected] ~]#


本文出自 “13091780” 博客,转载请与作者联系!

以上是关于一次/etc/hosts权限错误导致的es集群错误的主要内容,如果未能解决你的问题,请参考以下文章

【TCP Wrappers】关于/etc/hosts.allow /etc/hosts.deny

红帽linux下使用 vim /etc/hosts命令却无法编辑是怎么回事?

centos7中的/etc/rc.local文件权限问题

解决`source /etc/profile`报错问题

安装oracle数据库前把主机名和其IP 写入/etc/hosts 文件问题

ubuntu终端输入/etc/hosts.equiv怎么显示没那个文件或目录啊?