nova与虚拟机管理
DESCRIPTION
China OpenStack User GroupTRANSCRIPT
Nova与虚拟机管理戢友2012/11/10
Self-introduce• Eucalyptus 云计算 2010.5 ~2010.10
• OpenStack 企业私有云 2010.10~今
• 快速部署 +模块添加 +Nova定制
概要
Nova与虚拟机管理
Nova Traps and Pitfalls
Nova 开发 VS Eucalyptus开发
Nova在 OpenStack中的位置• Nova-Compute的结构
Nova的核心部件
Nova 源码分析• Hacking on OpenStack’s Nova Source code
• http://e.gensee.com/v_154692_2
• 重点 :
• 阅读源码 +按需定制与修改
• Make hands dirty.
• 虚拟机建立流程
Traps & Pitfalls
Compute服务的稳定性• Compute服务不稳定因素
• libvirt >= 0.9.13
经测试稳定。低版本的 libvirt有异步操作 bug。容易导致 libvirtd服务死掉。升级吧,不用犹豫了。
• 锁机制
compute模块在与 libvirt交互时,没有采用锁机制。
• 信息更新
compute模块有不少定时服务去刷 libvirt关于虚拟机的信息。
锁机制• 为了保证 libvirtd服务的正常运行。在compute通过 libvirt_connection访问 libvirt时,加了锁机制。
class Connection(object):
def __init__(self):
Connection.getInst()
__libvirt_conn = None
__inst = None
__lock = threading.Lock()
@property
def uri(self): ….
@staticmethod
def getInst():
auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_NOECHOPROMPT],
'root',
None]
Connection.__lock.acquire()
if not Connection.__libvirt_conn:
Connection.__inst = object.__new__(Connection)
object.__init__(Connection.__inst)
Connection.__libvirt_conn = libvirt.openAuth(Connection.__inst.uri, auth, 0)
Connection.__lock.release()
return Connection.__inst
@utils.synchronized('virt_libvirt_Connection', external=True)
def __getattr__(self,attr):
return getattr(Connection.__libvirt_conn, attr)
信息的更新• 改变传统的自顶向下的询问方式,采用自底向上的信息更新。
db.instance_get_all_by_host(host)
改为利用 libvirt收集到的本机的虚拟机,然后直接针对 instance进行更新:
db._instance_update()
虚拟机的快速启动• 常规启动多台虚拟机:
利用 qcow2快速启动•快速启动原理:
•增量文件只保存不一致的部分
backing_file
增量文件
Traps & Pitfalls• 通过 FLAGS.use_cow_images=True则使用快速启动。
• 增量文件的格式: qcow2
• Xen快速启动的陷阱
• Windows快速启动的缺陷
• 何时不应该使快速启动?
Xen快速启动Xen快速启动的条件 :
• Backing file格式需要使用 raw格式。
• 增量文件使用 qcow2格式。
• 需要用 Xen自带的 qemu-img工具生成 qcow2文件。不建议用标准的 qemu。因为 Xen的 stubdom就是一个修改过的 qemu。
• 底层 libvirt XML文件的配置 : <emulator>/usr/lib/xen/bin/qemu-dm</emulator> <disk type='file' device='disk'> <driver name='tap' type='qcow2'/> <source file='${basepath}/disk'/> <target dev='hda' bus='ide'/> </disk>
Windows的快速启动• Windows Image在移植至 OpenStack时,利用快速启动容易遇到蓝屏问题。
• 1、 virtio driver.
virtio-win-0.1-22.iso
virtio-win-1.1.16.vfd
• 2、 qcow2增量文件大小指定需要比原有
windows image大。一般 2~3倍没有问题。
何时不要使用快速启动• Qcow2文件缺点:
删除文件时,并没真正将文件从磁盘中删除。只是设置此文件失效。
如果需要在 Openstack的虚拟机中建立存储服务,不建议使用快速启虚拟机模式。
设置 :
/etc/nova/nova.conf
FLAGS.use_cow_images=False
Snapshot• Nova的 snapshot是针对磁盘而言,并没有做内存的 snapsh
ot。
• Nova做 Snapshot的大致流程:
Snapshot流程1 定位至相应的虚拟机。2 将虚拟机挂起:即内存保存至 checkpoint文件中。3 利用 qemu-img对磁盘建立 snapshot。4 整合磁盘文件与 snapshot生成一个新的独立的磁盘。5 将磁盘上传至 Glance服务。
利用 snapshot进行恢复
1 从 glance下载 image。2 利用这个新的 image启动一个虚拟机。
问题:Snapshot: 相当于把原有虚拟机的磁盘上传至 glance。
恢复 : 从 glance上下载此磁盘,新开一个虚拟机。和原来的虚拟机关系不大。
时间漫长………………………… .
快速 Snapshot
需求: 1、快速地做 Snapshot与恢复 2、必要时,才把 image上传至 Glance。 不用每次都上传。
步骤:1 做 snapshot:$qemu-img snapshot –c snapshot_name disk_path创建 snapshot.此时不用将 image上传至 glance2 恢复时:$ qemu-img snapshot –a snapshot_name disk_path亦不用从 glance下载磁盘进行恢复3 必要时,将虚拟机磁盘上传至 glanceimage_service.update(context, image_href, metadata, image_file)
快速 snapshot
优点1 并不是每次 snapshot都涉及到 glance。 都是在本地操作。因此可以很快地完成。2 可以把多次 snapshot放在一个磁盘里面, 直接上传至 Glance。不用把多个 snapshot单独上传。
快速 Snapshot
Note:
磁盘 snapshot针对 qcow2格式磁盘较易操作。对于 raw格式磁盘不易进行。
亦可以在针对磁盘做 snapshot时,同时对内存做 snapshot。这样可以做到对虚拟机的点恢复。
在做 snapshot时,建议用 qemu-img针对磁盘做 snapshot。利用 libvirt对内存做快照。不建议利用 libvirt提供的 snapshot功能。因为 libvirt提供的 snapshot在操作时,会把部分消息保存至 libivrt的数据库中。增删易造成不一致。
Terminate虚拟机
如果创建虚拟机失败。导致虚拟机并没有正常启动。那么 Terminate操作亦会失效。看一下流程:def do_terminate_instance(): elevated = context.elevated() instance = self.db.instance_get_by_uuid(elevated, instance_uuid) compute_utils.notify_usage_exists(instance, current_period=True) try: self._delete_instance(context, instance) except exception.InstanceTerminationFailure as error: msg = _('%s. Setting instance vm_state to ERROR') LOG.error(msg % error, instance_uuid=instance_uuid) self._set_instance_error_state(context, instance_uuid) except exception.InstanceNotFound as e: LOG.warn(e, instance_uuid=instance_uuid)
检测目标机器是否需要从glance下载backing file
根据block_migration决定是否需要迁移磁盘
Live Migration
Live Migration支持两种shared storage.
Non-shared storage.
为什么迁移经常出错?哪里出了问题?
检测目标机器
传入block_migration参数
block_migration决定是否迁移 VM的
image
是否迁移 image是由底层存储是否共享决
定
最终是否迁移 image由参数与底层存储决
定
Admin有 1000台机器,他并不清楚这两台机器是否是共享存
储
Live Migration 逻辑陷阱
Live Migration
不需参数指定。直接使用block_migration = self. mounted_on_same_shared_storage()
来进行决定。
CPU的比较底层基于 libvirt的 CPU比较过于严格,可以放松条件。厂商一致,型号差别不是太远,基本可以完成迁移。
Live Migration迁移时,去掉下面这个参数,则否会导致重新从 glance下载backing file.
image.cache(fetch_func=libvirt_utils.fetch_image,
context=ctxt,
filename=cache_name,
image_id=instance['image_ref'],
user_id=instance['user_id'],
project_id=instance['project_id'],
size=info['virt_disk_size'])
Live Migration什么时候可以使用总的前提条件:网络数据传输允许!数据传输有独立的通道!比如:可以的情况计算密集型 + 小磁盘: 迁移量 =内存 +增量磁盘计算节点之间采用共享存储允许小概率的迁移失败
不建议的情况:非共享存储 +大磁盘关键服务 +不允许迁移失败
Xen在 OpenStack状况
python-libvirt对 Xen的支持并不好。一些功能都不能实现。底层虚拟机启动配置需要修改。live_migration
pause/unpause
suspend/resume
save/restore
底层实现最好是利用 xen-tools来进行操作或者XenAPI。 Virsh在一定程度上也可以帮忙。
cc
clc
nc
OpenStack VS EucalyptusOpenStack
松耦合 /异步消息传递与函数调用python rest API易修改与定制
Eucalptus
上层发布 ec2接口的 java代码混乱模块连续紧密层层调用的消息传递与函数调用c/axis2c/WSDL开发调试难度加大
cc