nova虚拟机启动拉取image的过程
这里只关注Nova virt的spawn函数,glance、nova后端为ceph
nova/virt/libvirt/driver.pydefspawn(self,context,instance,p_w_picpath_meta,injected_files,admin_password,network_info=None,block_device_info=None):p_w_picpath_meta=objects.ImageMeta.from_dict(p_w_picpath_meta)disk_info=blockinfo.get_disk_info(CONF.libvirt.virt_type,instance,p_w_picpath_meta,block_device_info)self._create_p_w_picpath(context,instance,#虚拟机拉取glancep_w_picpathdisk_info['mapping'],network_info=network_info,block_device_info=block_device_info,files=injected_files,admin_pass=admin_password)xml=self._get_guest_xml(context,instance,network_info,disk_info,p_w_picpath_meta,block_device_info=block_device_info,write_to_disk=True)self._create_domain_and_network(context,xml,instance,network_info,disk_info,block_device_info=block_device_info)LOG.debug("Instanceisrunning",instance=instance)def_wait_for_boot():"""CalledatanintervaluntiltheVMisrunning."""state=self.get_info(instance).stateifstate==power_state.RUNNING:LOG.info(_LI("Instancespawnedsuccessfully."),instance=instance)raiseloopingcall.LoopingCallDone()timer=loopingcall.FixedIntervalLoopingCall(_wait_for_boot)#loopingcall等待虚拟机running的状态timer.start(interval=0.5).wait()nova/virt/libvirt/driver.pydef_create_p_w_picpath(self,context,instance,disk_mapping,suffix='',disk_p_w_picpaths=None,network_info=None,block_device_info=None,files=None,admin_pass=None,inject_files=True,fallback_from_host=None):booted_from_volume=self._is_booted_from_volume(#判断是不是boot_from_volume,boot_from_volume没有basep_w_picpathinstance)ifnotbooted_from_volume:root_fname=p_w_picpathcache.get_cache_fname(disk_p_w_picpaths,'p_w_picpath_id')size=instance.root_gb*units.Giifsize==0orsuffix=='.rescue':size=Nonebackend=p_w_picpath('disk')ifbackend.SUPPORTS_CLONE:#只有backend为rbd的才支持clone操作defclone_fallback_to_fetch(*args,**kwargs):try:backend.clone(context,disk_p_w_picpaths['p_w_picpath_id'])#clone操作在nova/virt/libvirt/p_w_picpathbackend.py中classRbd下exceptexception.ImageUnacceptable:#除p_w_picpath格式为raw和iso外的格式都抛异常libvirt_utils.fetch_p_w_picpath(*args,**kwargs)fetch_func=clone_fallback_to_fetchelse:fetch_func=libvirt_utils.fetch_p_w_picpathself._try_fetch_p_w_picpath_cache(backend,fetch_func,context,#进入_try_fetch_p_w_picpath_cache函数root_fname,disk_p_w_picpaths['p_w_picpath_id'],instance,size,fallback_from_host)。。。。。。。。#Fileinjectiononlyifneeded,#这里在OpenStackinOpenstack环境下注入密码有坑,从nova-computelog中看到一直卡在createp_w_picpath过程,#实际上是卡在密码注入过程。。。elifinject_filesandCONF.libvirt.inject_partition!=-2:ifbooted_from_volume:LOG.warn(_LW('Fileinjectionintoabootfromvolume''instanceisnotsupported'),instance=instance)self._inject_data(#注入相关的操作instance,network_info,admin_pass,files,suffix)ifCONF.libvirt.virt_type=='uml':libvirt_utils.chown(p_w_picpath('disk').path,'root')nova/virt/libvirt/p_w_picpathbackend.pydefclone(self,context,p_w_picpath_id_or_uri):p_w_picpath_meta=IMAGE_API.get(context,p_w_picpath_id_or_uri,include_locations=True)locations=p_w_picpath_meta['locations']LOG.debug('Imagelocationsare:%(locs)s'%{'locs':locations})ifp_w_picpath_meta.get('disk_format')notin['raw','iso']:#p_w_picpath格式判断,所以cephp_w_picpath格式最好是raw,这样走的ceph的clonereason=_('Imageisnotrawformat')raiseexception.ImageUnacceptable(p_w_picpath_id=p_w_picpath_id_or_uri,reason=reason)forlocationinlocations:ifself.driver.is_cloneable(location,p_w_picpath_meta):returnself.driver.clone(location,self.rbd_name)#调用nova/virt/libvirt/storage/rbd_utils.pyreason=_('Nop_w_picpathlocationsareaccessible')raiseexception.ImageUnacceptable(p_w_picpath_id=p_w_picpath_id_or_uri,reason=reason)nova/virt/libvirt/driver.pydef_try_fetch_p_w_picpath_cache(self,p_w_picpath,fetch_func,context,filename,p_w_picpath_id,instance,size,fallback_from_host=None):try:p_w_picpath.cache(fetch_func=fetch_func,#进入cache函数context=context,filename=filename,p_w_picpath_id=p_w_picpath_id,user_id=instance.user_id,project_id=instance.project_id,size=size)exceptexception.ImageNotFound:ifnotfallback_from_host:raiseLOG.debug("Image%(p_w_picpath_id)sdoesn'texistanymore""onp_w_picpathservice,attemptingtocopy""p_w_picpathfrom%(host)s",{'p_w_picpath_id':p_w_picpath_id,'host':fallback_from_host},instance=instance)defcopy_from_host(target,max_size):libvirt_utils.copy_p_w_picpath(src=target,dest=target,host=fallback_from_host,receive=True)p_w_picpath.cache(fetch_func=copy_from_host,filename=filename)nova/virt/libvirt/p_w_picpathbackend.pydefcache(self,fetch_func,filename,size=None,*args,**kwargs):"""Createsp_w_picpathfromtemplate.Ensuresthattemplateandp_w_picpathnotalreadyexists.Ensuresthatbasedirectoryexists.Synchronizesontemplatefetching.:fetch_func:Functionthatcreatesthebasep_w_picpathShouldaccept`target`argument.:filename:Nameofthefileinthep_w_picpathdirectory:size:Sizeofcreatedp_w_picpathinbytes(optional)"""@utils.synchronized(filename,external=True,lock_path=self.lock_path)deffetch_func_sync(target,*args,**kwargs):#Thep_w_picpathmayhavebeenfetchedwhileasubsequent#callwaswaitingtoobtainthelock.ifnotos.path.exists(target):#如果不存在basep_w_picpath的话fetch_func(target=target,*args,**kwargs)#fetch_func是clone_fallback_to_fetchbase_dir=os.path.join(CONF.instances_path,CONF.p_w_picpath_cache_subdirectory_name)ifnotos.path.exists(base_dir):fileutils.ensure_tree(base_dir)base=os.path.join(base_dir,filename)ifnotself.check_p_w_picpath_exists()ornotos.path.exists(base):self.create_p_w_picpath(fetch_func_sync,base,size,basep_w_picpath如果不存在的话,进入create_p_w_picpath*args,**kwargs)if(sizeandself.preallocateandself._can_fallocate()andos.access(self.path,os.W_OK)):utils.execute('fallocate','-n','-l',size,self.path)nova/virt/libvirt/p_w_picpathbackend.pydefcreate_p_w_picpath(self,prepare_template,base,size,*args,**kwargs):ifnotself.check_p_w_picpath_exists():prepare_template(target=base,max_size=size,*args,**kwargs)#prepare_template这里是fetch_func_sync#prepare_template()mayhaveclonedthep_w_picpathintoanewrbd#p_w_picpathalreadyinsteadofdownloadingitlocallyifnotself.check_p_w_picpath_exists():#如果走的是rbdclone操作,这里就不会用rbdimport了self.driver.import_p_w_picpath(base,self.rbd_name)self.verify_base_size(base,size)ifsizeandsize>self.get_disk_size(self.rbd_name):self.driver.resize(self.rbd_name,size)
总结: nova、glance后端为ceph,raw格式的p_w_picpath没有base p_w_picpath, qcow2格式还是有base p_w_picpath的,不过rbd import base p_w_picpath到pool后,可以把缓存的base p_w_picpath删除
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。