修改OpenStack VM中的resolv的search选项

前言

领导说要改一下OpenStack虚拟机中的resolv中的search的域,本以为是一个很简单的事情,三下两下就搞定了,果不其然的翻车了,不然也不会有这篇文章了…

修改过程

去官网的文档上看了一下,发现这个字段是受neutron.conf中的dns_domain控制的,改了之后运行虚拟机中的dhclient获取,发现,不对,怎么多了一个novalocal??

1
2
3
4
5
6
# dhclient
# cat /etc/resolv.conf
; generated by /usr/sbin/dhclient-script
search xx.com xxx1.com novalocal
nameserver 10.1.2.3
nameserver 10.1.2.4

会不会是cloud-init的操作?应该不会啊,还是看一下metadata

1
2
3
4
5
6
7
8
9
10
11
12
13
14
curl http://169.254.169.254/openstack/latest/meta_data.json | python -m json.tool
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 912 100 912 0 0 1304 0 --:--:-- --:--:-- --:--:-- 1306
{
"availability_zone": "nova",
"devices": [],
"hostname": "xxx.novalocal",
"launch_index": 0,
"name": "xxx",
"project_id": "ae39f633e6f14a578ab383b673f31f95",
"random_seed": "bWUqK7dMennhQp5OGtgOT9aI2hcBiM7hdg0SN5dfQB1kuvrnO5rqZAcEXtr7vgwHmeEuxSSzSDcf9YcGyoAg2+NgTplfp8FShzFjeTNJAMc9R5swuIuIXBqR65LDdIJVrIaG9L7ndJ71yfcMxWBprckxLAzgMHlIg4MQwLDLDCR9AIeX46gyQddzrzbuaRolZ0GWJjLCvEnq6AcPmYh9e9quhEuYkm1AwHdufrts52ivHLFBsW04zqMQ18ZBaRwX3ylBZbzOz3x1p2mqs+YYpGsWW4CcoTsIKvlfh3MAVLnkVFwxwjCzFYvX/TpnCETbsjfiPoJ74e9icKSeE1vSxqmLpRSyTV2ybmbt95g2SHjQSovndQiPnxZZY9+gR/CrNbDVylTIcxPgSJwXDkOZIxJBTm2CdSclll1p2dsZW6kEJlaho0bAV0/n9UKWoeQ8UHID2cdy0oSmqHrhdpDUG1Mb0wqKyzjvxOQN7ZpLKGfwLjHLHwPZr1LsY6IvTNhvhNpJB/GvKV6IlZxhM0LGggzgNxTBFf2XqYgQtAzX4W+ivTrikg9ILwBI2Ys/pWQMwE0G6hi5PJJMlKNsjZMiXfX/y1/uyu+vQ9DyDzLJgpJZaYXo9r4dF+AbnSDtY5YZMjRmyfYBwxPv5aGWIBE/nJUcyu2y3k0zWHbT4H2fBXk=",
"uuid": "0291b7c7-60e5-4945-9c64-2d5b0365dd5d"
}

之后在nova的代码当中找到了,dhcp_domain默认的值为novalocal(这个值是主要是在hostname后面一个域名,例如你的主机名为:aa,那创建后的主机名为:aa.novalocal)

1
2
3
4
5
# cat nova/conf/api.py
218 cfg.StrOpt("dhcp_domain",
219 deprecated_group="DEFAULT",
220 default="novalocal",
221 help="""

把这个配置指定为空之后,重新获取发现还是不对…

1
2
3
4
5
6
# dhclient
# cat /etc/resolv.conf
; generated by /usr/sbin/dhclient-script
search xx.com xxx1.com novalocal
nameserver 10.1.2.3
nameserver 10.1.2.4

之后我找到neutron-dhcp-agent对应的代码,看了一下这个字段到底是怎么拼接的,受哪些控制

1
2
3
4
5
6
7
8
9
@six.add_metaclass(abc.ABCMeta)
class DhcpBase(object):

def __init__(self, conf, network, process_monitor,
version=None, plugin=None):
self.conf = conf
self.network = network
self.dns_domain = (self.network.get('dns_domain') or
self.conf.dns_domain)

在上面的代码可以看到,self.dns_domain是受network.dns_domain这个值控制的,如果network.dns_domain的值为空,再去读配置文件中的dns_domain配置的值,我的环境中的网络中的dns_domain的值是为None的,所以肯定是会读配置文件中的,这里基本上就可以断定不是OpenStack的配置问题了,我就开始考虑是不是虚拟机哪里出了问题。

看了好久和也想了好久,metadata中是没有这些信息的,跟cloud-init没关系,毫无头绪,最后我看了一下虚拟机上面的hostname的全称,发现是xxx.novalocal,这个时候我就知道了,可能是dhcclient把这个加进去了,最后找到/usr/sbin/dhcclient-script中发现,确实是这样的,随后把hostnamenovalocal,再重新获取成功了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# cat /usr/sbin/dhclient
56 search="${1}"
57 if need_hostname; then
58 status=1
59 OLD_HOSTNAME=${HOSTNAME}
60 if [ -n "${new_ip_address}" ]; then
61 eval $(/bin/ipcalc --silent --hostname ${new_ip_address} ; echo "status=$?")
62 elif [ -n "${new_ip6_address}" ]; then
63 eval $(/bin/ipcalc --silent --hostname ${new_ip6_address} ; echo "status=$?")
64 fi
65
66 if [ ${status} -eq 0 ]; then
67 domain=$(echo $HOSTNAME | cut -s -d "." -f 2-)
68 fi
69 HOSTNAME=${OLD_HOSTNAME}
70 else
71 domain=$(hostname 2>/dev/null | cut -s -d "." -f 2-)
72 fi
73
74 if [ -n "${domain}" ] &&
75 [ ! "${domain}" = "localdomain" ] &&
76 [ ! "${domain}" = "localdomain6" ] &&
77 [ ! "${domain}" = "(none)" ] &&
78 [[ ! "${domain}" = *\ * ]]; then
79 is_in="false"
80 for s in ${search}; do
81 if [ "${s}" = "${domain}" ] ||
82 [ "${s}" = "${domain}." ]; then
83 is_in="true"
84 fi
85 done
86
87 if [ "${is_in}" = "false" ]; then
88 # Add domain name to search list (#637763)
89 sed -i -e "s/${search}/${search} ${domain}/" /etc/resolv.conf
90 fi
91 fi
92 }

验证一下

1
2
3
4
5
6
7
8
9
10
11
# hostname
xxx.novalocal

# hostnamectl set-hostname xxx

# dhclient
# cat /etc/resolv.conf
; generated by /usr/sbin/dhclient-script
search xx.com xxx1.com novalocal
nameserver 10.1.2.3
nameserver 10.1.2.4