【Nova】nova-network网络模型之flatdhcp网络-代码学习2
来源:互联网 发布:如何评价太祖知乎 编辑:程序博客网 时间:2024/05/21 17:52
在上一篇中,讲解了一下flatdhcp网络下nova-network服务在启动之前的准备工作:创建网桥、启动DNSmasq服务、添加iptables和ebtables规则等。
那这一篇,学习下创建虚拟机实例时,nova-network会进行的工作:
创建虚拟机实例时,nova-compute会通过rpc调用相应的(multi_host下通常就是自己所在主机上的)nova-network的allocate_for_instance API来为实例分配网络资源;
流程并不复杂,就是先为实例分配MAC地址然后分配固定IP,并在数据库进行记录;然后修改每个nova-network节点更新本地DNS的解析文件;最后修改DHCP服务的数据库文件,记录刚才分配的固定IP以及关联实例的主机名和MAC地址,并使DHCP优雅地重启;那么当实例启动后通过DHCP获取IP时,DHCP就把绑定其MAC地址的固定IP分配给它
class RPCAllocateFixedIP(object): servicegroup_api = None def _rpc_allocate_fixed_ip(self, context, instance_id, network_id, **kwargs): # 提高network_id获取network信息 network = self._get_network_by_id(context, network_id) # 调用NetworkManager中allocate_fixed_ip来分配固定IP, 指定了address就使用address对应的固定IP; # 如果没有指定, 就从固定IP池中选取一个未分配的与实例进行绑定 return self.allocate_fixed_ip(context, instance_id, network, **kwargs) def _allocate_fixed_ips(self, context, instance_id, host, networks, **kwargs): green_threads = [] vpn = kwargs.get('vpn') requested_networks = kwargs.get('requested_networks') for network in networks: address = None if requested_networks is not None: for address in (fixed_ip for (uuid, fixed_ip) in requested_networks if network['uuid'] == uuid): break # 如果不是multi_host模式, 说明只有一个nova-network节点; # 那么rpc调用的目标就是该节点 if not network['multi_host']: host = network['host'] # 如果参数host为空并且数据库中的网络信息没有记录host, 那么进行一次rpc调用让存在的nova-network节点返回自己的host信息 if host is None: network_p = obj_base.obj_to_primitive(network) host = self.network_rpcapi.set_network_host(context, network_p) if host != self.host: # 如果目标主机不是自己, 那么就意味着需要进行rpc调用; # 因为可能需要针对多个网络来进行rpc调用, 为了提高响应速度, 使用协程来进行, 让多个调用能同时进行 green_threads.append(eventlet.spawn( self.network_rpcapi._rpc_allocate_fixed_ip, context, instance_id, network['id'], address, vpn, host)) else: # 调用NetworkManager中allocate_fixed_ip来分配固定IP self.allocate_fixed_ip(context, instance_id, network, vpn=vpn, address=address) # 等待所有的协程处理完毕 for gt in green_threads: gt.wait() class NetworkManager(manager.Manager): # 获取requested_networks中的网络信息或者当前租户的所有网络信息 def _get_networks_for_instance(self, context, instance_id, project_id, requested_networks=None): if requested_networks is not None and len(requested_networks) != 0: network_uuids = [uuid for (uuid, fixed_ip) in requested_networks] networks = self._get_networks_by_uuids(context, network_uuids) else: networks = network_obj.NetworkList.get_by_project(context, project_id) return networks # 为实例分配一个固定IP, 要进行配额管理, 之前已经讲过, 大部分是数据库操作, # 在此不做赘述, 重点关注下分配完后的操作_setup_network_on_host def allocate_fixed_ip(self, context, instance_id, network, **kwargs): if kwargs.get('vpn', None): address = network['vpn_private_address'] fip = fixed_ip_obj.FixedIP.associate(context, address, instance_id, network['id'], reserved=True) else: address = kwargs.get('address', None) if address: fip = fixed_ip_obj.FixedIP.associate(context, address, instance_id, network['id']) else: fip = fixed_ip_obj.FixedIP.associate_pool(context, network['id'], instance_id) address = fip.address vif = vif_obj.VirtualInterface.get_by_instance_and_network( context, instance_id, network['id']) fip.allocated = True fip.virtual_interface_id = vif.id fip.save() if not kwargs.get('vpn', None): self._do_trigger_security_group_members_refresh_for_instance( instance_id) instance = instance_obj.Instance.get_by_uuid(context, instance_id) name = instance.display_name if self._validate_instance_zone_for_dns_domain(context, instance): self.instance_dns_manager.create_entry(name, address, "A", self.instance_dns_domain) self.instance_dns_manager.create_entry(instance_id, address, "A", self.instance_dns_domain) # 调用_setup_network_on_host, 需要具体的网络模式自行实现; # 分配了固定IP后还需要在主机上进行相应的设置工作 self._setup_network_on_host(context, network) return address # nova-compute创建实例时, 会通过rpc调用此方法为实例分配网络资源 def allocate_for_instance(self, context, **kwargs): instance_uuid = kwargs['instance_id'] if not uuidutils.is_uuid_like(instance_uuid): instance_uuid = kwargs.get('instance_uuid') host = kwargs['host'] project_id = kwargs['project_id'] rxtx_factor = kwargs['rxtx_factor'] requested_networks = kwargs.get('requested_networks') vpn = kwargs['vpn'] macs = kwargs['macs'] admin_context = context.elevated() LOG.debug(_("network allocations"), instance_uuid=instance_uuid, context=context) # 获取requested_networks中的网络信息或者当前租户的所有网络信息 networks = self._get_networks_for_instance(admin_context, instance_uuid, project_id, requested_networks=requested_networks) # 从networks中抽取出一部分的必需网络信息 networks_list = [self._get_network_dict(network) for network in networks] LOG.debug(_('networks retrieved for instance: |%s|'), networks_list, context=context, instance_uuid=instance_uuid) try: # 为实例的分配MAC地址并创建虚拟网卡的数据库记录 self._allocate_mac_addresses(context, instance_uuid, networks, macs) except Exception as e: with excutils.save_and_reraise_exception(): # 遇到异常时进行回滚并抛出 vif_obj.VirtualInterface.delete_by_instance_uuid(context, instance_uuid) # 为实例分配固定IP self._allocate_fixed_ips(admin_context, instance_uuid, host, networks, vpn=vpn, requested_networks=requested_networks) # 如果需要更新DNS记录 if CONF.update_dns_entries: network_ids = [network['id'] for network in networks] # 通知全部的nova-network包括自己更新本地解析文件, 并优雅的重启DHCP服务 self.network_rpcapi.update_dns(context, network_ids) # 返回实例的全部网络信息 return self.get_instance_nw_info(context, instance_uuid, rxtx_factor, host)class FlatDHCPManager(RPCAllocateFixedIP, floating_ips.FloatingIP, NetworkManager): # 该方法在准备工作中已经详细讲过了, 在分配固定IP后, 最主要的工作就是更新DHCP数据库记录 # 然后优雅重启DHCP服务 def _setup_network_on_host(self, context, network): network['dhcp_server'] = self._get_dhcp_ip(context, network) self.l3driver.initialize_network(network.get('cidr')) self.l3driver.initialize_gateway(network) if not CONF.fake_network: dev = self.driver.get_dev(network) elevated = context.elevated() # !这里才是本次设置的重点所在: # 更新DHCP数据库文件, 并优雅重启DHCP服务 self.driver.update_dhcp(elevated, dev, network) if CONF.use_ipv6: self.driver.update_ra(context, dev, network) gateway = utils.get_my_linklocal(dev) network.gateway_v6 = gateway network.save()
阅读全文
0 0
- 【Nova】nova-network网络模型之flatdhcp网络-代码学习2
- 【Nova】nova-network网络模型之flatdhcp网络-代码学习1
- 【Nova】nova-network网络模型之flatdhcp网络-代码学习3
- 【Nova】nova-network网络模型之flatdhcp网络
- 【Nova】nova-network网络模型之flat网络-代码学习
- 【Nova】nova-network网络模型之vlan网络-代码学习
- 【Nova】nova-network网络模型之flat网络
- 【Nova】nova-network网络模型之vlan网络
- 【nova】【nova-network】nova-network在FlatDHCP模型下给VM分配多网卡
- nova-network网络模式
- openstack 网络架构 nova-network + neutron
- openstack 网络架构 nova-network + neutron
- openstack 网络架构 nova-network + neutron
- openstack 网络架构 nova-network + neutron
- 【Nova】nova-compute代码学习2-状态机
- 【openstack】FlatDHCP模式单nova-network主机部署示例
- FlatDHCP模式单nova-network主机部署示例
- 【Nova】nova-compute代码学习4-防火墙
- nginx.conf
- html中的src与href的区别
- Oracle字符拼接函数中文乱码问题
- 常见面试题整理--数据库篇(每位开发者必备)
- MFC之Edit控件循环显示日志
- 【Nova】nova-network网络模型之flatdhcp网络-代码学习2
- 直播推流实现RTMP协议的一些注意事项
- 创建运动函数startMove(obj,attr,iTarget)
- 城市列表
- STL队列
- mysql远程访问错误:access denied for user xxxx@xxxx(using password:YES)
- Jury Marks <思维题>
- JFreeChart画图形插件的使用
- java初级开发面试题全集(下)