我遇到了 nfs 客户端无法解析可解析的 DNS 名称的问题。
[root@testserver-2 ~]# host nfs-server-host-name
nfs-server-host-name has address 10.37.4.131
[root@testserver-2 ~]# nslookup nfs-server-host-name
Server: 127.0.0.1
Address: 127.0.0.1#53
Name: nfs-server-host-name
Address: 10.37.4.126
[root@testserver-2 ~]# showmount -e nfs-server-host-name
clnt_create: RPC: Unknown host
[root@testserver-2 ~]# ss -lnp |grep rpc
LISTEN 0 128 *:111 *:* users:(("rpcbind",7627,8)
[root@testserver-2 ~]# mount -t nfs -o defaults,auto,proto=tcp nfs-server-host-name:/ifs/exports/EXPORT /mnt/export
mount.nfs: Failed to resolve server nfs-server-host-name: Name or service not known
通过 dnsmasq 设置本地解析:
[root@testserver-2 ~]# cat /etc/resolv.conf
options rotate timeout:2 attempts:4
nameserver 127.0.0.1
nameserver 10.1.1.1
nameserver 8.8.8.8
[root@testserver-2 ~]# cat /etc/dnsmasq.conf
resolv-file=/etc/resolv.conf
server=/nfs-server-host-name/10.37.4.1 #IP address of Isilon smart connect resolver
listen-address=127.0.0.1
nsswitch 配置(默认 Centos 6):
[root@testserver-2 ~]# grep hosts /etc/nsswitch.conf
hosts: files dns
请注意,nfs-server-host-name
解析由 Isilon 智能连接解析器处理,该解析器通过 dnsmasq 配置为nfs-server-host-name
本地解析器并正常工作(如上例所示)。nfs-server-host-name
无法用 IP 地址替换,因为有多个 NFS 节点由解析器平衡,因此 IP 是可变的,无法硬编码。因此,上述来自 hosts 和 nslookup 的两个结果不同是可以接受的。这是预期的和有意为之的行为。
还请注意,这nfs-server-host-name
是主机名的一个非常精确的示例。实际主机名看起来几乎完全相同,它不是 FQDN。事实上,主机名中根本没有点。这是我无法控制的功能。
当使用一个有效节点 IP 地址手动挂载时,导出挂载正常。当将一个节点的地址放入时/etc/hosts
,它会挂载。当通过 DNS 解析时,它不适用于 nfs 客户端,但适用于其他网络工具,例如 hosts、dig 或 ping。
这似乎不是一个常见的问题,但到目前为止我发现的所有提示都说“用 IP 替换主机名”,这是我无法做到的。
我错过了什么?
答案1
我还没弄清楚真实的问题是,但解决方案是删除rotate
选项/etc/resolv.conf
和nfs-server-host-name
在 in后面放一个点/etc/fstab
以防止域搜索(即使在 没有search
选项时也会发生这种情况/etc/resolv.conf
),即:
nfs-server-host-name.:/nfs/export/...
^
^---up here
这可能与内核构建选项 CONFIG_NFS_USE_LEGACY_DNS 有关,该选项设置为是的在我的内核上。
nfs-client(和 nfs-client 独有)的行为是,它只查询第二无论有多少个名称服务器,/etc/resolv.conf
只要rotate
有该选项,它都可以工作。但是,当根本没有第二个名称服务器时,它确实有效。难倒我了...
答案2
该showmount
命令有一个 RPC 调用,用于gethostbyname_r
尝试获取主机名的信息。它对解释其返回的错误没有多大作用。您可以运行测试来查看错误实际上是什么吗?此代码是根据实际clnt_gen.c
看到的 glibc 代码修改而来的这里
C 语言源代码示例:
#include <netdb.h>
#include <alloca.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(int argc, char **argv)
{
struct hostent hostbuf, *h;
size_t hstbuflen;
char *hsttmpbuf;
char *hostname;
int herr;
if (argc != 2)
{
exit(-1);
}
hostname = argv[1];
hstbuflen = 1024;
hsttmpbuf = alloca(hstbuflen);
while (gethostbyname_r (hostname, &hostbuf, hsttmpbuf, hstbuflen, &h, &herr) != 0 || h == NULL)
{
if (herr != NETDB_INTERNAL || errno != ERANGE)
{
printf("gethostbyname_r error: %s\n", hstrerror(herr));
exit(0);
}
else
{
hstbuflen *= 2;
hsttmpbuf = alloca (hstbuflen);
}
}
}
将其另存为ghbntest.c
并使用命令进行编译gcc -o ghbntest ghbntest.c
。使用运行./ghbntest nfs-server-host-name
。输出示例:
$ ./ghbntest 12345.example.com
gethostbyname_r error: Unknown host