修改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,再重新获取成功了

Read More

OpenStack 使用TAP/TUN设备

OpenStack Neutron

TAP/TUN

虚拟设备和物理设备的区别

在Linux内核中有一个网络设备管理层,处于网络设备驱动和协议栈之间,负责衔接它们之间的数据交互。驱动不需要了解协议栈的细节,协议栈也不需要了解设备驱动的细节。

对于一个网络设备来说,就像一个管道(pipe)一样,有两端,从其中任意一端收到的数据将从另一端发送出去。

比如一个物理网卡eth0,它的两端分别是内核协议栈(通过内核网络设备管理模块间接的通信)和外面的物理网络,从物理网络收到的数据,会转发给内核协议栈,而应用程序从协议栈发过来的数据将会通过物理网络发送出去。

对于一个虚拟的网络设备,首先它也归内核的网络设备管理子系统管理,对于Linux内核网络设备管理模块来说,虚拟设备和物理设备没有区别,都是网络设备,都能配置IP,从网络设备来的数据,都会转发给协议栈,协议栈过来的数据,也会交由网络设备发送出去,至于是怎么发送出去的,发到哪里去,那是设备驱动的事情,跟Linux内核就没关系了,所以说虚拟网络设备的一端也是协议栈,而另一端是什么取决于虚拟网络设备的驱动实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
+-----------------------------------------------+
| |
| +-------------+ |
| |Application A| | User Stack
| +-------------+ |
| |↑ |
| || |
|········||·····································|
| || +-----------> +--------+ |
| || |+----------- |tun/tap0| |
| || || +--------+ |
| || || ↑| |
| ↓| ↓| |↓ |
| +------------+ +----------------------+ | Kernel Stack
| |/dev/net/tun| |Network Protocol Stack| |
| +------------+ +----------------------+ |
| |
+-----------------------------------------------+

实现tun/tap设备的内核模块为tun,其模块介绍为Universal TUN/TAP device driver,该模块提供了一个设备接口/dev/net/tun供用户层程序读写,用户层程序通过读写/dev/net/tun来向主机内核协议栈注入数据或接收来自主机内核协议栈的数据,可以把tun/tap看成数据管道,它一端连接主机协议栈,另一端连接用户程序
为了使用tun/tap设备,用户层程序需要通过系统调用打开/dev/net/tun获得一个读写该设备的文件描述符(FD),并且调用ioctl()向内核注册一个TUN或TAP类型的虚拟网卡(实例化一个tun/tap设备),其名称可能是tap7b7ee9a9-c1/vnetXX/tunXX/tap0等。此后,用户程序可以通过该虚拟网卡与主机内核协议栈交互。当用户层程序关闭后,其注册的TUN或TAP虚拟网卡以及路由表相关条目(使用tun可能会产生路由表条目,比如openvpn)都会被内核释放。可以把用户层程序看做是网络上另一台主机,他们通过tap虚拟网卡相连。

TAP TUN的区别

TUN和TAP设备区别在于他们工作的协议栈层次不同,TAP等同于一个以太网设备,用户层程序向tap设备读写的是二层数据包如以太网数据帧,tap设备最常用的就是作为虚拟机网卡。TUN则模拟了网络层设备,操作第三层数据包比如IP数据包,openvpn使用TUN设备在C/S间建立VPN隧道

Read More