openstack创建instance的流程

workflow:




1. 用户向nova-api发送请求

用户发送请求到nova-api,这里有两种:
    a.通过openstack api
        从 server.py's controller.create():
Python代码   收藏代码
  1. self.helper.create_instance(req, body, self.compute_api.create)    

        create_instance_helper.CreateInstanceHelper()  查表获取基本信息
    b.通过ec2 api
       从cloud.py.run_instances()

统一调  computer.api.create() 将新的数据插回去

Python代码   收藏代码
  1. self._ask_scheduler_to_create_instance(context, base_options,  
  2.                                        instance_type, zone_blob,  
  3.                                        availability_zone, injected_files,  
  4.                                        admin_password, image,  
  5.                                        instance_id=instance_id,  
  6.                                        requested_networks=requested_networks)    

  
2. API 将处理好的数据通过MQ 转发给scheduler .(code from Computer.api)
 
Python代码   收藏代码
  1. rpc.cast(context,  
  2.             FLAGS.scheduler_topic,  
  3.             {"method""run_instance",  
  4.              "args": {"topic": FLAGS.compute_topic,  
  5.                       "instance_id": instance_id,  
  6.                       "request_spec": request_spec,  
  7.                       "availability_zone": availability_zone,  
  8.                       "admin_password": admin_password,  
  9.                       "injected_files": injected_files,  
  10.                       "requested_networks": requested_networks}})  

3. Scheduler  获取信息并作出决定 哪一个host 可以来run instance.
 
Python代码   收藏代码
  1. def __getattr__(self, key):  
  2.     return functools.partial(self._schedule, key)  

Python代码   收藏代码
  1. def _schedule(self, method, context, topic, *args, **kwargs):  
  2.     .......  
  3.     rpc.cast(context,  
  4.              db.queue_get_for(context, topic, host),  
  5.              {"method": method,  
  6.               "args": kwargs})  
  7.     LOG.debug(_("Casted to %(topic)s %(host)s for %(method)s") % locals())  

4. Computer 从池中获取信息 并让 Networker 去准备一个ip ,让volume 准备卷, 然后初始化相应的信息,例如创建image,映射device,创建domain,
   并将domain 放入running pool中  然后就进入等待直到instance的状态变为running.


       a. networker 分配ip
Python代码   收藏代码
  1. network_info = self.network_api.allocate_for_instance(context,  
  2.                           instance, vpn=is_vpn,  
  3.                           requested_networks=requested_networks)  


Python代码   收藏代码
  1. def allocate_floating_ip(self, context):  
  2.    return rpc.call(context,  
  3.                    FLAGS.network_topic,  
  4.                    {'method''allocate_floating_ip',  
  5.                     'args': {'project_id': context.project_id}})  





b  让 volume 准备卷

Python代码   收藏代码
  1. bd_mapping = self._setup_block_device_mapping(context, instance_id)  
  2. def create(self, context, size, snapshot_id, name, description,  
  3.           volume_type=None, metadata=None, availability_zone=None):  
  4.          rpc.cast(context,  
  5.                       FLAGS.scheduler_topic,  
  6.                               {"method""create_volume",  
  7.                                    "args": {"topic": FLAGS.volume_topic,  
  8.                                    "volume_id": volume['id'],  
  9.                                     "snapshot_id": snapshot_id}})  

     c   call nova.virt.libvirt.firewall.IptablesFirewallDriver 建立网络规则
           这里是重头戏,单独开个贴记录下....
      d  call libvirt 创建domian 并launch
Python代码   收藏代码
  1. domain = self._create_new_domain(xml)  
  2. def _create_new_domain(self, xml, persistent=True, launch_flags=0):  
  3.     if persistent:  
  4.                # To create a persistent domain, first define it, then launch it.  
  5.                domain = self._conn.defineXML(xml)  
  6.                domain.createWithFlags(launch_flags)  
  7.    else:  
  8.                # createXML call creates a transient domain  
  9.                domain = self._conn.createXML(xml, launch_flags)  
  10.    return domain  


e  call virt.libvirt.connetion.spwan 等待

Python代码   收藏代码
  1.  def spawn(self, context, instance, network_info,  
  2.       block_device_info=None):  
  3.        ..........  
  4.        def _wait_for_boot():  
  5.              instance_name = instance['name']  
  6.             try:  
  7.                     state = self.get_info(instance_name)['state']  
  8.             except exception.NotFound:  
  9.                     msg = _("During reboot, %s disappeared.") % instance_name  
  10.                      LOG.error(msg)  
  11.              raise utils.LoopingCallDone  
  12.   
  13.             if state == power_state.RUNNING:  
  14.                 msg = _("Instance %s spawned successfully.") % instance_name  
  15.                 LOG.info(msg)  
  16.                 raise utils.LoopingCallDone  
  17.   
  18. timer = utils.LoopingCall(_wait_for_boot)  
  19. return timer.start(interval=0.5, now=True)  
    

5 一旦instance的状态改变至running,他就会去通过networker获取网络信息, 这里有几种方式,取决于你的networkManager
     详细请见上一步c
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值