首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

openstack创设instance的流程

2012-06-30 
openstack创建instance的流程workflow:1. 用户向nova-api发送请求用户发送请求到nova-api,这里有两种:a.通

openstack创建instance的流程
workflow:




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

用户发送请求到nova-api,这里有两种:
    a.通过openstack api
        从 server.py's controller.create():

        self.helper.create_instance(req, body, self.compute_api.create)  

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

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

 self._ask_scheduler_to_create_instance(context, base_options,                                        instance_type, zone_blob,                                        availability_zone, injected_files,                                        admin_password, image,                                        instance_id=instance_id,                                        requested_networks=requested_networks)  

  
2. API 将处理好的数据通过MQ 转发给scheduler .(code from Computer.api)
 
     rpc.cast(context,                 FLAGS.scheduler_topic,                 {"method": "run_instance",                  "args": {"topic": FLAGS.compute_topic,                           "instance_id": instance_id,                           "request_spec": request_spec,                           "availability_zone": availability_zone,                           "admin_password": admin_password,                           "injected_files": injected_files,                           "requested_networks": requested_networks}})

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

    def _schedule(self, method, context, topic, *args, **kwargs):        .......        rpc.cast(context,                 db.queue_get_for(context, topic, host),                 {"method": method,                  "args": kwargs})        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
          network_info = self.network_api.allocate_for_instance(context,                                    instance, vpn=is_vpn,                                    requested_networks=requested_networks)


         def allocate_floating_ip(self, context):            return rpc.call(context,                            FLAGS.network_topic,                            {'method': 'allocate_floating_ip',                             'args': {'project_id': context.project_id}})





b  让 volume 准备卷

           bd_mapping = self._setup_block_device_mapping(context, instance_id)           def create(self, context, size, snapshot_id, name, description,                     volume_type=None, metadata=None, availability_zone=None):                    rpc.cast(context,                                 FLAGS.scheduler_topic,                                         {"method": "create_volume",                                              "args": {"topic": FLAGS.volume_topic,                                              "volume_id": volume['id'],                                               "snapshot_id": snapshot_id}})

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


e  call virt.libvirt.connetion.spwan 等待

         def spawn(self, context, instance, network_info,              block_device_info=None):               ..........               def _wait_for_boot():                     instance_name = instance['name']                    try:                            state = self.get_info(instance_name)['state']                    except exception.NotFound:                            msg = _("During reboot, %s disappeared.") % instance_name                             LOG.error(msg)                     raise utils.LoopingCallDone                    if state == power_state.RUNNING:                        msg = _("Instance %s spawned successfully.") % instance_name                        LOG.info(msg)                        raise utils.LoopingCallDone        timer = utils.LoopingCall(_wait_for_boot)        return timer.start(interval=0.5, now=True)
    

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

热点排行