本文简单介绍一下neutron中metadata是如何对接nova-metadtata为虚拟机提供metadata服务的。
1. Metadata服务简介
OpenStack的Metadata服务主要是为虚拟机提供配置信息。在虚拟机启动的时候,会向Metadata服务请求自己的metadata信息,然后执行cloud-init的时候完成个性化配置。
1.1 工作流程
整个的工作流程如下图所示。经过neutron-metadata-agent进行转发的原因是,nova-api-metadata服务运行在管理网络,而虚拟机是运行在业务网络,两者可能不能通信。而在neutron-metadata-agent之前又嫁接一层neutron-ns-metadata-proxy的原因是在openstack中,不同的网络可以配置相同的CIDR,nova-api-metadata无法根据虚拟机的ip来判定虚拟机的id,所以需要在neutron-ns-metadata-agent服务添加network-id后者router-id。这样就可以根据instance ip,network-id/router-id来获取到唯一的虚拟机id。
- 虚拟机启动的时候会配置默认路由
虚拟机启动的时候,会进行默认路由的配置,配置访问169.254.169.254的路由信息 - 虚拟机请求169.254.169.254
请求到达qrouter-<network-id>
或者qdhcp-<network-id>
的网络命名空间。如果该网络没有配置router,是到达qdhcp-<network-id>
的网络命名空间,如果配有router,会到达qrouter-<network-id>
的网络命名空间。 - 请求到达
qrouter-<network-id>
或者qdhcp-<network-id>
网络命名空间
请求到达网络命名空间以后,经由neutron-ns-metadata-proxy,添加router-id或者network-id,然后通过socket转发给neutron-metadata-agent。 - 请求通过unix socket转发给neutron-metadata-agent服务
neutron-metadata-agent通过请求头部的network-id/router-id以及请求的ip地址,获取到instance id,将请求转发给nova-api-metadata。 - neutron-metadata-agent服务将请求转发给nova-api-metadata。
nova-api-metadata根据instance id回复metadata response。
2. 基于qrouter-<network-id>
命名空间的metadata服务实现
当openstack中的网络连接router时,neutron-metadata-agent通过qrouter-<network-id>
网络命名空间来提供metadata服务。
此时,登录虚拟机,看一下路由规则。可以看到在请求169.254.169.254时,通过gateway进行转发,而gateway是配置在qrouter-<network-id>
网络命名空间下的
1 | #虚拟机路由 |
那么请求在qrouter-<network-id>
的命名空间是如何转发的呢?答案是通过iptables
1 | [root@tstack-con01 ~]# ip netns exec qrouter-f8156a50-cf9e-430c-a8a6-64a87e41fd01 iptables-save|grep 169 |
会把对169.254.169.254,80端口的请求转发到9697端口。而9697端口就运行着neutron-ns-metadata-proxy服务,该服务实际上是一个haproxy进行。
1 | [root@tstack-con01 ~]# ip netns exec qrouter-f8156a50-cf9e-430c-a8a6-64a87e41fd01 lsof -i:9697 |
查看一下配置文件/var/lib/neutron/ns-metadata-proxy/
1 | [root@tstack-con01 ~]# cat /var/lib/neutron/ns-metadata-proxy/f8156a50-cf9e-430c-a8a6-64a87e41fd01.conf |
实际上neutron-ns-metadata-proxy用过socket连接neutron-metadata-agent,然后在请求头部添加router-id,neutorn-metadata-agent就会根据请求的ipd地址和router-id获取到虚拟机的id。然后将请求发送给nova-api-metadata服务。
3. 基于qdhcp-<network-id>
命名空间的metadata服务实现
如果网络没有绑定router,那么neutron通过qdhcp-<network-id>
网络命名空间来处理metadata请求。
此时的实现方式,会在qdhcp-<network-id>
网络命名空间添加一个169.254.169.254的网卡。
1 | [root@openstack-con01 ~]# ip netns exec qdhcp-35a559be-9f45-4d4e-849f-6c58b7e8ddd1 ip a |
neutron-ns-metadata-proxy运行在80端口,实际就是一个haproxy服务。这样对169.254.169.254的80端口的访问都会直接到达该服务。
1 | [root@openstack-con01 ~]# ip netns exec qdhcp-35a559be-9f45-4d4e-849f-6c58b7e8ddd1 lsof -i:80 |
看一下haproxy的配置文件,实际上通过socket连接neutron-metadata-agent,然后在请求的头部添加network id。这样neutron-metadata-agent就可以通过虚拟机的ip和network的id来获取instance id,然后想nova-api-metadata请求对应instance的metadata信息。
1 | [root@openstack-con01 ~]# cat /var/lib/neutron/ns-metadata-proxy/35a559be-9f45-4d4e-849f-6c58b7e8ddd1.conf |
4. 源码分析
- neutron-ns-metadata-proxy的配置文件生成代码 view code
- neutron-metadata-agent的处理函数 view code
- neutron-metadata-agent从请求中获取虚拟机ip,router-id/network-id,然后根据这些信息获取虚拟机的id view code
- neutron-metadata-agent把请求转发给nova-api-metadata view code
参考文档