一、服务简介:
在云计算中,Metadata 并不是一个陌生的概念。从字面上看,Metadata 是元数据的意思。而在云计算中,Metadata 服务能够向虚机注入一些额外的信息,这样虚机在创建之后可以有一些定制化的配置。在 OpenStack 中,Metadata 服务能够向虚机提供主机名,ssh 公钥,用户传入的一些定制数据等其他信息。这些数据被分为两类:metadata和user data,metadata主要包括虚机自身的一些数据比如hostname、ssh秘钥、网络配置等,而user data主要包括一些定制的脚本、命令等。但是不管是哪一种数据,openstack向虚机提供数据的方式是一致的。
二、服务提供方式:
在 OpenStack 中,虚拟机获取 Metadata 信息的方式有两种:Config drive 和 metadata RESTful 服务。首先肯定的是提供metadata服务的组件是nova,而nova提供了两种方式,一种直接通过nova-api服务提供,另外一种是通过nova-api-metadata服务提供,现在基本就是nova-api来提供metadata服务了。
三、metadata早期实现方法:
在早期的openstack版本中,大概F版之前没有neutron组件,网络由nova-network提供,也没有现在这么复杂的namespace,虚机的ip地址是不重复的,此时metadata的实现主要通过添加路由规则实现,这里还要提到169.254.169.254/32 这个地址,主要是早期亚马逊提出的metadata理念,openstack沿用了这个地址而已,早期实现代码如下:
明显随着openstack的发展,多租户的网络隔离网络不再那么简单单一,虚机ip地址的重叠比比皆是,此时只通过增加一条转发规则明显是不够的,因为相同ip的虚机传来请求我们无法识别,此时就衍生了neutron-metadata-agent、neutron-ns-metadata-proxy等服务,但是其核心思路还是沿用的。
四、metadata服务的数据请求路径
显而易见虚机现在请求metadata服务器的服务麻烦多了,但流程还是清晰的,上图提供了两种方式:dhcp-namespace 和 qrouter-namespace,接下来我们从配置入手分别详细介绍一下这两种请求路径是如何工作的。
①vim /etc/nova/nova.conf
②vim /etc/neutron/metadata_agent.ini
通过以上两个配置文件不难看出metadat_listen、metadata_port两个配置项指定了metadata服务端实际监听的端口与ip地址,而service_metadata_proxy选项设置为true说明通过了neutron的metadata porxy服务连接虚机,同时设置了neutron与nova的metadata服务连接的secret秘钥,两边保持一致即可,nova_metadata_ip, nova_metadata_port 这两个与前面metadata_listen, metadata_listen_port 保持一致。这两个配置告诉 neutron-metadata-agent 从哪可以得到 Metadata 服务。由此我们可以看到nova的metadata服务于neutron的neutron-metadat-agent服务关联到了一起。
nova的metadata服务于neutron的neutron-metadata-agent服务的联系很好理解,不同网络中的虚机 正是通过此服务与metadata服务端通讯的,下面我们就要介绍不同的namespace中的虚机又是如何与neutron-metadata-agent通讯的,这里就要引入neutron的另一个服务neutron-ns-metadata-proxy,此服务运行在namespace中。
有关neutron-ns-metadata-proxy服务,我们要从两方面讲述,
一种是用户创建了vrouter并且需要metadata的虚机网络连接到了VRouter,查看相关配置:
vim /etc/neutron/l3_agent.ini
注:在L版中metadata_port,metadata_proxy_socket两个选项为已经变为默认配置
vim /usr/lib/python2.7/site-packages/neutron/agent/metadata/namespace_proxy.py
虚拟机启动后会向169.254.169.254请求数据,首先到达虚机网关,我们进入虚机路由查看规则
我们发现虚机发往169.254.169.254的80端口的包都给转到了9697端口,外部访问9697端口的包都丢弃了,我们可以从下图看到监听9697的正是neutron-ns-metadata-proxy服务,通过 Unix Domain socket,neutron-ns-metadata-proxy 将虚机的请求发送到了 neutron-metadata-agent。结合前面的描述,虚机的请求最终会发送到 Nova Metadata 服务
neutron-ns-metadata-proxy 进程会随 virtual router 的创建而创建,同时也会随 virtual router 的移除而终止。在 OpenStack Kilo 版本中,支持 legacy router,HA router,DVR 与 neutron-ns-metadata-proxy 一同工作。从用户的角度,不用考虑这些不同类型的 virtual router 对 Metadata 的影响。
前面讲述了有vrouter的情况,下面我们介绍
另外一种没有vrouter是如何请求metadata数据的:
vim /etc/neutron/dhcp_agent.ini
从配置可以看出在没有vrouter的时候会 通过dhcp的namesapce来通讯。我们看如下虚机的路由表,其中多出一条指向169.254.169.254的规则,这条规则会直接把 Metadata 数据请求发送到 dhcp server 上。在 dhcp 的 namespace 里面,neutron-ns-metadata-proxy 直接监听在 80 端口,所以在 iptables 里面看不到什么特别的规则。neutron-ns-metadata-proxy 与 neutron-metadata-agent 的连接与前面一样,这里就不再赘述了。
注!以上截图来自openstack的L版,为什么这里 neutron-ns-metadata-proxy 可以直接监听在 80 端口,而前面不行?因为 virtual router 的 namespace 要承接 L3 服务,80 端口作为一个常用的端口如果被 Metadata 占用将非常不方便。而在 dhcp 的 namespace 中,80 端口本来没有使用,就没有必要做转发,可以直接使用。
在 dhcp namespace 中,neutron-ns-metadata-proxy 进程会随 network 的 dhcp server 的创建而创建。同样的,从用户的角度不用考虑管理 neutron-ns-metadata-proxy 进程。