当前在OpenStack中没有提供一个方便快捷的方法去创建镜像,需要运维人员使用KVM制作,这无疑提高了对运维人员和环境
(需要一个安装了KVM的linux)的要求,因此我觉得OpenStack还是不适应于私有云的,它是为公有云而生。
本文介绍一种利用Horizon和ISO格式的安装盘来创建镜像的方法,其原理为:
1. 创建一个新的磁盘作为root disk
2. 从Glance下载ISO作为第二块磁盘
3. 从Glance下载virtio作为第三块磁盘
4. 从ISO启动虚拟机,比将系统安装到root disk
5. 创建image并保持到Glance
1.添加一种disk类型newos
* 'mapping': a dict contains the storage device mapping.
For the default disk types it will contain the following
keys & values:
'disk' -> disk_info
'disk.rescue' -> disk_info
'disk.local' -> disk_info
'disk.swap' -> disk_info
'disk.config' -> disk_info
'disk.newos' -> disk_info
disk_info指的是:
* 'disk_info': a tuple specifying disk configuration
It contains the following 3 fields
(disk bus, disk dev, device type)
* 'disk_bus': the guest bus type ('ide', 'virtio', 'scsi', etc)
* 'disk_dev': the device name 'vda', 'hdc', 'sdf', 'xvde' etc
* 'device_type': type of device eg 'disk', 'cdrom', 'floppy'
2 设置磁盘顺序
在blockinfo.py中,调用逻辑是:
spawn-->get_disk_info -->get_disk_mapping :
if image_meta and image_meta.get('disk_format') == 'iso':
root_disk_bus = disk_bus
#创建虚拟机时如果image_meta中的disk_format为iso, 则认为是创建新image的操作,那么进行如下操作
#设置disk.newos为root device
root_device_type = 'disk'
root_info = get_next_disk_info(mapping,
root_disk_bus,
root_device_type)
mapping['root'] = root_info
mapping['disk.newos'] = root_info
#设置disk(iso)为第二个device
image_device_type = 'cdrom'
image_device_bus = cdrom_bus
cdrom_info = get_next_disk_info(mapping,
image_device_bus,
image_device_type)
mapping['disk'] = cdrom_info
#s设置disk.virtio作为第三个设备,为需要virtio的时候提供virtio驱动程序
virtio_device_type = 'cdrom'
virtio_device_bus = cdrom_bus
virtio_device_info = get_next_disk_info(mapping,
virtio_device_bus,
virtio_device_type)
mapping['disk.virtio'] = virtio_device_info
return mapping
3 创建磁盘
driver.py中的调逻辑是:spawn--> _create_image
newos_size_gb = CONF.os_root_disk_size
if 'disk.newos' in disk_mapping:
fname = "newos_%s_%s" % (newos_size_gb, os_type_with_default)
size = newos_size_gb * 1024 * 1024 * 1024
image('disk.newos').cache(fetch_func=self._create_newos,
filename=fname,
size=size,
newos_size=newos_size_gb)
virtio_image_id = CONF.virtio_image_id
virtio_images = {'image_id': virtio_image_id}
virtio_fname = imagecache.get_cache_fname(virtio_images, 'image_id')
image('disk.virtio').cache(fetch_func=libvirt_utils.fetch_image,
context=context,
filename=virtio_fname,
size=size,
image_id=virtio_image_id,
user_id=instance['user_id'],
project_id=instance['project_id'])
@staticmethod
def _create_newos(target, newos_size):
#self._create_local(target, newos_size)
unit='G'
libvirt_utils.create_image('qcow2', target,
'%d%c' % (newos_size, unit))
4. 将磁盘配置写入XML文件中
driver.py中的调逻辑是:spawn-->get_guest_xml--> get_guest_config-->_get_guest_storage_config
if rescue:
diskrescue = self.get_guest_disk_config(instance,
'disk.rescue',
disk_mapping,
inst_type)
devices.append(diskrescue)
diskos = self.get_guest_disk_config(instance,
'disk',
disk_mapping,
inst_type)
devices.append(diskos)
else:
#添加device
if 'disk.newos' in disk_mapping:
disknewos = self.get_guest_disk_config(instance,
'disk.newos',
disk_mapping,
inst_type)
devices.append(disknewos)
diskcdrom = self.get_guest_disk_config(instance,
'disk',
disk_mapping,
inst_type)
devices.append(diskcdrom)
diskvirtio = self.get_guest_disk_config(instance,
'disk.virtio',
disk_mapping,
inst_type)
devices.append(diskvirtio)
###
else:
if 'disk' in disk_mapping:
diskos = self.get_guest_disk_config(instance,
'disk',
disk_mapping,
inst_type)
devices.append(diskos)