Metadata 概述

Metadata 概述

  1. 虚拟机metadata服务背景

在创建虚拟机的时候,用户往往需要对虚拟机进行一些配置,比如:开启一些服务、安装某些包、添加SSH 秘钥、配置 hostname,修改密码等等。这里有两个问题,一个是谁负责初始化虚拟机配置,另一个是虚拟机如何获取到这些配置信息的。cloud-init负责初始化虚拟机配置,那么虚拟机如何获取到用户传递的配置信息呢?OpenStack提供了两种方式获取这些配置信息,一种是config drive,一种是metadata RESTful服务。由于篇幅关系,本文主要阐述metadata RESTful服务。

  1. 虚拟机获取metadata流程
    在这里插入图片描述
    如上图所示,虚拟机获取metadata 的大致流程为:首先请求被发送至neutron-ns-metadata-proxy,此时会在请求中添加router-id 和network-id,然后请求通过unix domian socket 被转发给neutron-metadata-agent,根据请求中的router-id、network-id 和IP,获取port 信息,从而拿到instance-id 和tenant-id 加入请求中,最后请求被转发给nova-api-metadata,其利用instance-id 和tenant-id 获取虚拟机的metadata,返回相应。
    上面我们分析了各个服务之间转发请求的流程,那么现在只存在一个问题,整个获取metadata 的路线就通畅了:虚拟机如何将请求发送至neutron-ns-metadata-proxy? neutron通过两种方式来解决这个问题:通过router 发送请求和通过DHCP 发送请求。

  2. 通过DHCP发送请求

如果虚拟机所在subnet 没有连接在任何router 上,那么请求则无法通过router 转发。此时 neutron 通过DHCP 服务器来转发metadata 请求。从 下图可以看到DHCP 服务器的IP 配置信息,发现DHCP 服务器配置了两个IP,其中一个就是169.254.169.254。并且DHCP服务器对应的neutron-ns-metadata-proxy监听着80端口,从而发向169.254.169.254 的报文会被发至neutron-ns-metadata-proxy。

在这里插入图片描述
通过代码可以看出来,如果配置了enable_isolated_metadata,DHCP服务会配置多一个metadata 服务IP

if self.conf.force_metadata or self.conf.enable_isolated_metadata:
    ip_cidrs.append(constants.METADATA_CIDR)
    if netutils.is_ipv6_enabled():
        ip_cidrs.append(constants.METADATA_V6_CIDR)

注意:在启动dhcp的时候,如果是dhcp方式的metadata,可以看到dhcp会配置一条静态路由,该静态路由会被推送到虚拟机上,169.254.169.254的数据包被直接交给DHCP所在的服务器处理

在这里插入图片描述在这里插入图片描述
对应代码:

if ((self.conf.force_metadata or
     (isolated_subnets[subnet.id] and
         self.conf.enable_isolated_metadata)) and
        subnet.ip_version == 4):
    subnet_dhcp_ip = subnet_to_interface_ip.get(subnet.id)
    if subnet_dhcp_ip:
        host_routes.append(
            '%s,%s' % (constants.METADATA_CIDR, subnet_dhcp_ip)
        )
  1. 通过router发送请求

登录虚拟机,看一下路由规则。可以看到在请求169.254.169.254时,通过gateway进行转发,而gateway是配置在qrouter-<network-id> 网络命名空间下的

那么请求在qrouter-<network-id>的命名空间是如何转发的呢?答案是通过iptables

[root@tstack-con01 ~]# ip netns exec qrouter-f8156a50-cf9e-430c-a8a6-64a87e41fd01 iptables-save|grep 169
-A neutron-l3-agent-PREROUTING -d 169.254.169.254/32 -i qr-+ -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 9697
-A neutron-l3-agent-PREROUTING -d 169.254.169.254/32 -i qr-+ -p tcp -m tcp --dport 80 -j MARK --set-xmark 0x1/0xffff

会把对169.254.169.254,80端口的请求转发到9697端口。而9697端口就运行着neutron-ns-metadata-proxy服务,该服务实际上是一个haproxy进行。

[root@tstack-con01 ~]# ip netns exec qrouter-f8156a50-cf9e-430c-a8a6-64a87e41fd01 lsof -i:9697COMMAND     PID    USER   FD   TYPE   DEVICE SIZE/OFF NODE NAMEhaproxy 1592727 neutron    4u  IPv4 27760235      0t0  TCP *:9697 (LISTEN)[root@tstack-con01 ~]# ip netns exec qrouter-f8156a50-cf9e-430c-a8a6-64a87e41fd01 ps -aux|grep 1592727neutron  1592727  0.0  0.0  47940  1196 ?        Ss   Feb01   0:01 haproxy -f /var/lib/neutron/ns-metadata-proxy/f8156a50-cf9e-430c-a8a6-64a87e41fd01.confroot     1856176  0.0  0.0 112708   952 pts/1    S+   00:34   0:00 grep --color=auto 1592727[root@tstack-con01 ~]#

实际上neutron-ns-metadata-proxy用过socket连接neutron-metadata-agent,然后在请求头部添加router-id,neutorn-metadata-agent就会根据请求的ipd地址和router-id获取到虚拟机的id。然后将请求发送给nova-api-metadata服务。

代码上实现是,router agent会发送after router add事件到metadata agent,然后添加iptables规则以及开启metadata_proxy服务。

def after_router_added(resource, event, l3_agent, payload):
    router = payload.latest_state
    proxy = l3_agent.metadata_driver
    apply_metadata_nat_rules(router, proxy)
    if not isinstance(router, ha_router.HaRouter):
        spawn_kwargs = {}
        if netutils.is_ipv6_enabled():
            spawn_kwargs['bind_address'] = '::'
        proxy.spawn_monitored_metadata_proxy(
            l3_agent.process_monitor,
            router.ns_name,
            proxy.metadata_port,
            l3_agent.conf,
            router_id=router.router_id,
            **spawn_kwargs)

注意:DHCP服务会额外在添加一条默认路由(及虚机对应的子网的网关),如果虚机访问metadata服务,会默认访问到具体的子网的网关,也就是对应的qr口。
5. 参考文章

https://lk668.github.io/2020/10/12/2020-10-12-neutron-metadata/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值